openapi: 3.0.3 info: title: 'Dukanam Mobile API' description: 'Interactive reference for the versioned Dukanam API, covering authentication, billing, POS, inventory, GST, compliance, exports, and team access.' version: 1.0.0 servers: - url: 'https://dukanam.com' tags: - name: Authentication description: "\nCreate and manage mobile bearer tokens." - name: Businesses description: '' - name: 'Business onboarding' description: "\nComplete the resumable setup required after registering a new business. Until onboarding finishes,\nclients may resubmit a completed required step to correct saved data without moving the current step backwards." - name: Contacts description: '' - name: 'Khata ledger' description: '' - name: Inventory description: '' - name: 'Sales invoices' description: '' - name: 'Business documents' description: '' - name: Payments description: '' - name: Expenses description: "\nExpense records are a core Purchases capability on every plan. Workspace purchase permissions still apply." - name: POS description: '' - name: 'Cash register' description: '' - name: Reports description: '' - name: 'Business compliance guidance' description: '' - name: 'GST compliance' description: '' - name: Billing description: '' - name: 'Data exports' description: '' - name: 'Team access' description: "\nOwners and administrators can manage workspace members. Smart Books supports one accountant seat in addition to the owner. Business supports all documented roles, with five total seats including the owner and pending invitations." - name: 'Team invitations' description: '' - name: 'Billing webhooks' description: '' - name: Lookups description: "\nSearch tenant-scoped values for lookup controls. Results are limited to the active business and the caller's workspace permissions and plan features." - name: 'Payment accounts' description: '' components: securitySchemes: default: type: http scheme: bearer description: 'Use the API test login above. A successful login automatically copies the returned `data.token` into every authenticated endpoint and keeps it across page reloads.' security: - default: [] paths: /api/v1/auth/register: post: summary: '' operationId: postApiV1AuthRegister description: '' parameters: [] responses: {} tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Must not be greater than 128 characters.' example: b email: type: string description: 'Must be a valid email address. Must not be greater than 255 characters.' example: zbailey@example.net phone: type: string description: 'Must not be greater than 32 characters.' example: i nullable: true business_name: type: string description: 'Must not be greater than 128 characters.' example: 'y' password: type: string description: 'Must be at least 8 characters.' example: pBNvYg device_name: type: string description: 'A name for the device token.' example: 'Scribe API Docs' required: - name - email - business_name - password - device_name security: [] /api/v1/auth/login: post: summary: '' operationId: postApiV1AuthLogin description: '' parameters: [] responses: {} tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'Must be a valid email address.' example: gbailey@example.net password: type: string description: '' example: '|]|{+-' remember: type: boolean description: '' example: false device_name: type: string description: 'A name for the device token.' example: 'Scribe API Docs' required: - email - password - device_name security: [] /api/v1/auth/forgot-password: post: summary: 'Email a password reset link.' operationId: emailAPasswordResetLink description: 'Always returns the same response so callers cannot discover registered email addresses.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'If an account exists for that email address, a password reset link has been sent.' properties: message: type: string example: 'If an account exists for that email address, a password reset link has been sent.' tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: 'The account email address.' example: owner@example.com required: - email security: [] /api/v1/auth/reset-password: post: summary: 'Reset an account password.' operationId: resetAnAccountPassword description: 'A successful reset revokes every mobile bearer token and sends a security notification.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: message: 'Password reset successfully. Sign in with your new password.' properties: message: type: string example: 'Password reset successfully. Sign in with your new password.' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: email: - 'This password reset token is invalid.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - 'This password reset token is invalid.' items: type: string tags: - Authentication requestBody: required: true content: application/json: schema: type: object properties: token: type: string description: 'The token delivered in the password-reset email.' example: reset-token email: type: string description: 'The account email address.' example: owner@example.com password: type: string description: 'The new password, at least eight characters.' example: new-secure-password password_confirmation: type: string description: 'Must match password.' example: new-secure-password required: - token - email - password - password_confirmation security: [] /api/v1/auth/me: get: summary: 'Return the current user and active workspaces available under each plan and seat assignment.' operationId: returnTheCurrentUserAndActiveWorkspacesAvailableUnderEachPlanAndSeatAssignment description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Authentication /api/v1/auth/token: delete: summary: '' operationId: deleteApiV1AuthToken description: '' parameters: [] responses: {} tags: - Authentication /api/v1/auth/tokens: delete: summary: '' operationId: deleteApiV1AuthTokens description: '' parameters: [] responses: {} tags: - Authentication /api/v1/businesses: get: summary: "List the active workspaces available under the caller's current plan and seat assignment." operationId: listTheActiveWorkspacesAvailableUnderTheCallersCurrentPlanAndSeatAssignment description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Businesses '/api/v1/businesses/{business}': get: summary: '' operationId: getApiV1BusinessesBusiness description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Businesses parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/settings': patch: summary: 'Update business settings.' operationId: updateBusinessSettings description: "The `default_locale` field may only be changed by workspace owners and admins. Manual-sharing\ntemplates may only be changed by those roles when the paid feature is enabled for the business." parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 1 name: 'Anika Stores' slug: anika-stores role: owner phone: '9876543210' email: anika@example.com legal_name: 'Anika Stores Private Limited' gstin: 27AAPFU0939F1ZV gst_registration_type: regular currency: INR timezone: Asia/Kolkata address: line_1: '12 Market Road' line_2: null city: Pune state_code: '27' pincode: '411001' default_place_of_supply: '27' invoice_prefix: INV prices_include_tax: true upi_id: anikastores@bank theme: indigo default_locale: hi is_active: true manual_sharing: enabled: true reminder_message_template: 'Hello {customer_name}, your current balance is {amount_due}.' reminder_email_subject_template: 'Payment reminder from {business_name}' invoice_share_subject_template: 'Invoice {invoice_number} from {business_name}' invoice_share_message_template: 'Hello {customer_name}, invoice {invoice_number} for {invoice_total} is ready.' subscription: status: active billing_interval: monthly trial_ends_at: null renews_at: '2026-09-19T00:00:00.000000Z' ends_at: null cancelled_at: null plan: id: 2 name: Smart slug: smart features: - inventory - pos - expenses limits: [] properties: data: type: object properties: id: type: integer example: 1 name: type: string example: 'Anika Stores' slug: type: string example: anika-stores role: type: string example: owner phone: type: string example: '9876543210' email: type: string example: anika@example.com legal_name: type: string example: 'Anika Stores Private Limited' gstin: type: string example: 27AAPFU0939F1ZV gst_registration_type: type: string example: regular currency: type: string example: INR timezone: type: string example: Asia/Kolkata address: type: object properties: line_1: type: string example: '12 Market Road' line_2: type: string example: null nullable: true city: type: string example: Pune state_code: type: string example: '27' pincode: type: string example: '411001' default_place_of_supply: type: string example: '27' invoice_prefix: type: string example: INV prices_include_tax: type: boolean example: true upi_id: type: string example: anikastores@bank theme: type: string example: indigo default_locale: type: string example: hi is_active: type: boolean example: true manual_sharing: type: object properties: enabled: type: boolean example: true reminder_message_template: type: string example: 'Hello {customer_name}, your current balance is {amount_due}.' reminder_email_subject_template: type: string example: 'Payment reminder from {business_name}' invoice_share_subject_template: type: string example: 'Invoice {invoice_number} from {business_name}' invoice_share_message_template: type: string example: 'Hello {customer_name}, invoice {invoice_number} for {invoice_total} is ready.' subscription: type: object properties: status: type: string example: active billing_interval: type: string example: monthly trial_ends_at: type: string example: null nullable: true renews_at: type: string example: '2026-09-19T00:00:00.000000Z' ends_at: type: string example: null nullable: true cancelled_at: type: string example: null nullable: true plan: type: object properties: id: type: integer example: 2 name: type: string example: Smart slug: type: string example: smart features: type: array example: - inventory - pos - expenses items: type: string limits: type: array example: [] tags: - Businesses requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Must not be greater than 128 characters.' example: b legal_name: type: string description: 'Must not be greater than 191 characters.' example: 'n' nullable: true phone: type: string description: 'Must not be greater than 32 characters.' example: g nullable: true email: type: string description: 'Must be a valid email address. Must not be greater than 255 characters.' example: rowan.gulgowski@example.com nullable: true gst_registration_type: type: string description: '' example: unregistered enum: - unregistered - regular - composition gstin: type: string description: 'Must match the regex /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/. Must be 15 characters.' example: dljnikhwaykcmyu nullable: true address_line_1: type: string description: 'Must not be greater than 191 characters.' example: w nullable: true address_line_2: type: string description: 'Must not be greater than 191 characters.' example: p nullable: true city: type: string description: 'Must not be greater than 96 characters.' example: w nullable: true state_code: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true pincode: type: string description: 'Must be 6 digits.' example: '569775' nullable: true default_place_of_supply: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true invoice_prefix: type: string description: 'Invoice-series prefix, up to 15 characters. GST permits letters, numbers, hyphens, and slashes; the generated invoice number is limited to 16 characters.' example: HAWIOT/26-27/ prices_include_tax: type: boolean description: '' example: false authorized_signatory: type: string description: 'Must not be greater than 128 characters.' example: g nullable: true bank_details: type: string description: 'Must not be greater than 1000 characters.' example: z nullable: true upi_id: type: string description: 'Must match the regex /^[a-zA-Z0-9._-]{2,191}@[a-zA-Z0-9.-]{2,63}$/. Must not be greater than 255 characters.' example: m nullable: true theme: type: string description: '' example: blue enum: - blue - emerald - teal - violet - rose - maroon - graphite nullable: true default_locale: type: string description: '' example: en enum: - en - hi - ta - te - ml - kn - mr - gu - bn reminder_message_template: type: string description: 'Must not be greater than 2000 characters.' example: i nullable: true reminder_email_subject_template: type: string description: 'Must not be greater than 191 characters.' example: 'y' nullable: true invoice_share_subject_template: type: string description: 'Must not be greater than 191 characters.' example: v nullable: true invoice_share_message_template: type: string description: 'Must not be greater than 2000 characters.' example: d nullable: true required: - name - gst_registration_type - invoice_prefix parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/dashboard': get: summary: '' operationId: getApiV1BusinessesBusinessDashboard description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Businesses parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding': get: summary: '' operationId: getApiV1BusinessesBusinessOnboarding description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Business onboarding' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding/language': patch: summary: '' operationId: patchApiV1BusinessesBusinessOnboardingLanguage description: '' parameters: [] responses: {} tags: - 'Business onboarding' requestBody: required: true content: application/json: schema: type: object properties: locale: type: string description: 'Supported locale code.' example: hi required: - locale parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding/business': post: summary: '' operationId: postApiV1BusinessesBusinessOnboardingBusiness description: '' parameters: [] responses: {} tags: - 'Business onboarding' requestBody: required: true content: multipart/form-data: schema: type: object properties: name: type: string description: 'Public business name.' example: 'Veera Stores' store_type: type: string description: 'Store type key.' example: kirana-store supply_type: type: string description: 'goods, services, or both.' example: goods phone: type: string description: 'Public phone in E.164 or a 10-digit Indian local format.' example: '9876543210' logo: type: string format: binary description: 'Optional PNG, JPG, or WebP logo up to 2 MB.' nullable: true required: - name - store_type - supply_type - phone parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding/tax': patch: summary: '' operationId: patchApiV1BusinessesBusinessOnboardingTax description: '' parameters: [] responses: {} tags: - 'Business onboarding' requestBody: required: true content: application/json: schema: type: object properties: gst_status: type: string description: 'registered, not_registered, or not_sure.' example: registered gst_registration_type: type: string description: 'Required when registered: normal or composition.' example: normal nullable: true gstin: type: string description: 'Required when registered.' example: 29ABCDE1234F1Z5 nullable: true legal_name: type: string description: 'Must not be greater than 191 characters.' example: a nullable: true address_line_1: type: string description: '' example: '12 Market Road' address_line_2: type: string description: 'Must not be greater than 191 characters.' example: k nullable: true city: type: string description: '' example: Bengaluru state_code: type: string description: 'Indian GST state code.' example: '29' pincode: type: string description: 'Six digit PIN code.' example: '560001' required: - gst_status - address_line_1 - city - state_code - pincode parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding/steps/{step}': post: summary: '' operationId: postApiV1BusinessesBusinessOnboardingStepsStep description: '' parameters: [] responses: {} tags: - 'Business onboarding' requestBody: required: false content: application/json: schema: type: object properties: skip: type: boolean description: 'Set true to finish this optional step later.' example: true parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: step description: 'The step.' example: architecto required: true schema: type: string '/api/v1/businesses/{business}/onboarding/product-imports': post: summary: '' operationId: postApiV1BusinessesBusinessOnboardingProductImports description: '' parameters: [] responses: {} tags: - 'Business onboarding' requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 'Completed Dukanam XLSX template, maximum 5 MB.' required: - file parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/onboarding/product-imports/{itemImport_id}/confirm': post: summary: "Import every validated product row without exceeding the current plan's total item allowance." operationId: importEveryValidatedProductRowWithoutExceedingTheCurrentPlansTotalItemAllowance description: '' parameters: [] responses: 422: description: '' content: application/json: schema: type: object example: message: 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' errors: plan: - 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' properties: message: type: string example: 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' errors: type: object properties: plan: type: array example: - 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' items: type: string tags: - 'Business onboarding' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: itemImport_id description: 'The ID of the itemImport.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/contacts': get: summary: '' operationId: getApiV1BusinessesBusinessContacts description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Contacts requestBody: required: false content: application/json: schema: type: object properties: type: type: string description: '' example: customer enum: - customer - supplier - both nullable: true search: type: string description: 'Must not be greater than 128 characters.' example: b nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 nullable: true post: summary: 'Create a contact and post its opening balance.' operationId: createAContactAndPostItsOpeningBalance description: 'Customer openings post to Accounts receivable; supplier openings post to Accounts payable, offset by Owner equity.' parameters: [] responses: {} tags: - Contacts requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: '' example: customer enum: - customer - supplier - both profile_type: type: string description: '' example: consumer enum: - consumer - business name: type: string description: 'Must not be greater than 128 characters.' example: b company_name: type: string description: 'Must not be greater than 191 characters.' example: 'n' nullable: true contact_person: type: string description: 'Must not be greater than 128 characters.' example: g nullable: true phone: type: string description: 'Must not be greater than 32 characters.' example: z nullable: true email: type: string description: 'Must be a valid email address. Must not be greater than 255 characters.' example: rempel.chadrick@example.org nullable: true gst_treatment: type: string description: '' example: unregistered enum: - unregistered - registered_regular - registered_composition - consumer - overseas - sez gstin: type: string description: 'Must match the regex /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/. Must be 15 characters.' example: ljnikhwaykcmyuw nullable: true pan: type: string description: 'Must match the regex /^[A-Z]{5}[0-9]{4}[A-Z]$/. Must be 10 characters.' example: pwlvqwrsit nullable: true address: type: string description: 'Must not be greater than 1000 characters.' example: c nullable: true billing_address_line_1: type: string description: 'Must not be greater than 191 characters.' example: p nullable: true billing_address_line_2: type: string description: 'Must not be greater than 191 characters.' example: s nullable: true billing_city: type: string description: 'Must not be greater than 96 characters.' example: c nullable: true billing_state_code: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true billing_pincode: type: string description: 'Must be 6 digits.' example: '569775' nullable: true shipping_same_as_billing: type: boolean description: '' example: false shipping_address_line_1: type: string description: 'Must not be greater than 191 characters.' example: 'n' nullable: true shipping_address_line_2: type: string description: 'Must not be greater than 191 characters.' example: g nullable: true shipping_city: type: string description: 'Must not be greater than 96 characters.' example: z nullable: true shipping_state_code: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true shipping_pincode: type: string description: 'Must be 6 digits.' example: '569775' nullable: true opening_balance: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 22 nullable: true opening_balance_side: type: string description: '' example: receivable enum: - receivable - payable opening_balance_date: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true required: - type - profile_type - name - gst_treatment - opening_balance_side parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/contacts/{id}': get: summary: '' operationId: getApiV1BusinessesBusinessContactsId description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Contacts put: summary: 'Update a contact and replace its opening-balance journal.' operationId: updateAContactAndReplaceItsOpeningBalanceJournal description: '' parameters: [] responses: {} tags: - Contacts requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: '' example: customer enum: - customer - supplier - both profile_type: type: string description: '' example: consumer enum: - consumer - business name: type: string description: 'Must not be greater than 128 characters.' example: b company_name: type: string description: 'Must not be greater than 191 characters.' example: 'n' nullable: true contact_person: type: string description: 'Must not be greater than 128 characters.' example: g nullable: true phone: type: string description: 'Must not be greater than 32 characters.' example: z nullable: true email: type: string description: 'Must be a valid email address. Must not be greater than 255 characters.' example: rempel.chadrick@example.org nullable: true gst_treatment: type: string description: '' example: unregistered enum: - unregistered - registered_regular - registered_composition - consumer - overseas - sez gstin: type: string description: 'Must match the regex /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/. Must be 15 characters.' example: ljnikhwaykcmyuw nullable: true pan: type: string description: 'Must match the regex /^[A-Z]{5}[0-9]{4}[A-Z]$/. Must be 10 characters.' example: pwlvqwrsit nullable: true address: type: string description: 'Must not be greater than 1000 characters.' example: c nullable: true billing_address_line_1: type: string description: 'Must not be greater than 191 characters.' example: p nullable: true billing_address_line_2: type: string description: 'Must not be greater than 191 characters.' example: s nullable: true billing_city: type: string description: 'Must not be greater than 96 characters.' example: c nullable: true billing_state_code: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true billing_pincode: type: string description: 'Must be 6 digits.' example: '569775' nullable: true shipping_same_as_billing: type: boolean description: '' example: false shipping_address_line_1: type: string description: 'Must not be greater than 191 characters.' example: 'n' nullable: true shipping_address_line_2: type: string description: 'Must not be greater than 191 characters.' example: g nullable: true shipping_city: type: string description: 'Must not be greater than 96 characters.' example: z nullable: true shipping_state_code: type: string description: '' example: 1 enum: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 - 21 - 22 - 23 - 24 - 26 - 27 - 29 - 30 - 31 - 32 - 33 - 34 - 35 - 36 - 37 - 38 - 97 - 99 nullable: true shipping_pincode: type: string description: 'Must be 6 digits.' example: '569775' nullable: true opening_balance: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 22 nullable: true opening_balance_side: type: string description: '' example: receivable enum: - receivable - payable opening_balance_date: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true required: - type - profile_type - name - gst_treatment - opening_balance_side delete: summary: '' operationId: deleteApiV1BusinessesBusinessContactsId description: '' parameters: [] responses: {} tags: - Contacts parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: id description: 'The ID of the contact.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/ledger-entries': get: summary: '' operationId: getApiV1BusinessesBusinessLedgerEntries description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Khata ledger' requestBody: required: false content: application/json: schema: type: object properties: contact_id: type: integer description: '' example: 16 nullable: true kind: type: string description: 'Must not be greater than 32 characters.' example: 'n' nullable: true from: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true to: type: string description: 'Must be a valid date. Must be a date after or equal to from.' example: '2026-01-15' nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 nullable: true post: summary: 'Post a manual khata adjustment.' operationId: postAManualKhataAdjustment description: 'The receivable or payable adjustment is offset to Owner equity. Use invoice, purchase, expense, and payment endpoints for operational transactions.' parameters: [] responses: {} tags: - 'Khata ledger' requestBody: required: true content: application/json: schema: type: object properties: contact_id: type: integer description: '' example: 16 kind: type: string description: '' example: customer_credit enum: - customer_credit - customer_payment - supplier_credit - supplier_payment amount: type: number description: 'Must not be greater than 999999999.' example: 22 occurred_on: type: string description: 'Must be a valid date.' example: '2026-01-15' reference: type: string description: 'Must not be greater than 64 characters.' example: g nullable: true note: type: string description: 'Must not be greater than 1000 characters.' example: z nullable: true required: - contact_id - kind - amount - occurred_on parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/ledger-entries/{ledgerEntry_id}': get: summary: '' operationId: getApiV1BusinessesBusinessLedgerEntriesLedgerEntry_id description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Khata ledger' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: ledgerEntry_id description: 'The ID of the ledgerEntry.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/ledger-entries/{ledgerEntry_id}/reverse': post: summary: 'Reverse a manual khata adjustment and its journal.' operationId: reverseAManualKhataAdjustmentAndItsJournal description: '' parameters: [] responses: {} tags: - 'Khata ledger' requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'Must be at least 3 characters. Must not be greater than 255 characters.' example: b required: - reason parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: ledgerEntry_id description: 'The ID of the ledgerEntry.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/items': get: summary: '' operationId: getApiV1BusinessesBusinessItems description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Inventory requestBody: required: false content: application/json: schema: type: object properties: search: type: string description: 'Must not be greater than 128 characters.' example: b nullable: true low_stock: type: boolean description: '' example: false nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 nullable: true post: summary: 'Create an item and post opening inventory.' operationId: createAnItemAndPostOpeningInventory description: "Tracked opening stock creates a balanced Inventory / Owner equity journal at purchase cost.\nStock and reorder quantities accept up to three decimal places." parameters: [] responses: 422: description: '' content: application/json: schema: type: object example: message: 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' errors: plan: - 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' properties: message: type: string example: 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' errors: type: object properties: plan: type: array example: - 'Your current plan includes up to 5 items. Upgrade to Smart Books to add more.' items: type: string tags: - Inventory requestBody: required: true content: multipart/form-data: schema: type: object properties: name: type: string description: 'Must not be greater than 128 characters.' example: b sku: type: string description: 'Must not be greater than 64 characters.' example: 'n' nullable: true barcode: type: string description: 'Must not be greater than 64 characters.' example: g nullable: true item_type: type: string description: '' example: goods enum: - goods - service hsn_sac: type: string description: 'Must match the regex /^[0-9A-Z.\-]+$/. Must not be greater than 16 characters.' example: zmiyvdljnikhwayk nullable: true unit: type: string description: 'Must not be greater than 24 characters.' example: cmyuwpwlvqwrsitc uqc: type: string description: 'Must not be greater than 16 characters.' example: pscqldzsnrwtujwv gst_taxability: type: string description: '' example: taxable enum: - taxable - nil_rated - exempt - non_gst sale_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 24 purchase_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 9 nullable: true mrp: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 15 nullable: true tax_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 21 nullable: true cess_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 7 nullable: true stock_quantity: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 8 reorder_level: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 10 nullable: true track_inventory: type: boolean description: '' example: false price_includes_tax: type: boolean description: '' example: false photos: type: array description: 'Must be an image. Must not be greater than 5120 kilobytes.' items: type: string format: binary remove_photos: type: array description: '' example: - 16 items: type: integer required: - name - item_type - unit - uqc - gst_taxability - sale_price - stock_quantity parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/items/{id}': get: summary: '' operationId: getApiV1BusinessesBusinessItemsId description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Inventory put: summary: 'Update an item and account for stock corrections.' operationId: updateAnItemAndAccountForStockCorrections description: "Quantity increases post inventory-adjustment income; decreases post an operating expense.\nStock and reorder quantities accept up to three decimal places." parameters: [] responses: {} tags: - Inventory requestBody: required: true content: multipart/form-data: schema: type: object properties: name: type: string description: 'Must not be greater than 128 characters.' example: b sku: type: string description: 'Must not be greater than 64 characters.' example: 'n' nullable: true barcode: type: string description: 'Must not be greater than 64 characters.' example: g nullable: true item_type: type: string description: '' example: goods enum: - goods - service hsn_sac: type: string description: 'Must match the regex /^[0-9A-Z.\-]+$/. Must not be greater than 16 characters.' example: zmiyvdljnikhwayk nullable: true unit: type: string description: 'Must not be greater than 24 characters.' example: cmyuwpwlvqwrsitc uqc: type: string description: 'Must not be greater than 16 characters.' example: pscqldzsnrwtujwv gst_taxability: type: string description: '' example: taxable enum: - taxable - nil_rated - exempt - non_gst sale_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 24 purchase_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 9 nullable: true mrp: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 15 nullable: true tax_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 21 nullable: true cess_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 7 nullable: true stock_quantity: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 8 reorder_level: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 10 nullable: true track_inventory: type: boolean description: '' example: false price_includes_tax: type: boolean description: '' example: false photos: type: array description: 'Must be an image. Must not be greater than 5120 kilobytes.' items: type: string format: binary remove_photos: type: array description: '' example: - 16 items: type: integer required: - name - item_type - unit - uqc - gst_taxability - sale_price - stock_quantity delete: summary: '' operationId: deleteApiV1BusinessesBusinessItemsId description: '' parameters: [] responses: {} tags: - Inventory parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: id description: 'The ID of the item.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/invoices': get: summary: '' operationId: getApiV1BusinessesBusinessInvoices description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Sales invoices' requestBody: required: false content: application/json: schema: type: object properties: status: type: string description: '' example: posted enum: - posted - partially_paid - paid - void - partially_returned - returned nullable: true contact_id: type: integer description: '' example: 16 nullable: true from: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true to: type: string description: 'Must be a valid date. Must be a date after or equal to from.' example: '2026-01-15' nullable: true search: type: string description: 'Must not be greater than 128 characters.' example: 'n' nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 7 nullable: true post: summary: 'Create a sales invoice.' operationId: createASalesInvoice description: '' parameters: [] responses: {} tags: - 'Sales invoices' requestBody: required: true content: application/json: schema: type: object properties: contact_id: type: integer description: '' example: 16 issue_date: type: string description: 'Must be a valid date.' example: '2026-01-15' due_date: type: string description: 'Must be a valid date. Must be a date after or equal to issue_date.' example: '2026-01-15' nullable: true notes: type: string description: 'Must not be greater than 2000 characters.' example: 'n' nullable: true place_of_supply_state_code: type: string description: 'Must be 2 characters.' example: gz nullable: true reverse_charge: type: boolean description: '' example: false prices_include_tax: type: boolean description: '' example: false channel: type: string description: '' example: backoffice enum: - backoffice - pos nullable: true idempotency_key: type: string description: 'Must be a valid UUID.' example: 977e5426-8d13-3824-86aa-b092f8ae52c5 nullable: true lines: type: array description: 'Must have at least 1 items. Must not have more than 50 items.' example: - [] items: type: object properties: item_id: type: integer description: '' example: 16 nullable: true description: type: string description: 'Must not be greater than 255 characters.' example: 'Et animi quos velit et fugiat.' quantity: type: number description: 'Must not be greater than 999999.' example: 1 unit_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 5 tax_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 19 nullable: true cess_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 17 nullable: true discount: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 5 nullable: true price_includes_tax: type: boolean description: '' example: false required: - description - quantity - unit_price required: - contact_id - issue_date - lines parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/invoices/{invoice_id}': get: summary: '' operationId: getApiV1BusinessesBusinessInvoicesInvoice_id description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Sales invoices' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: invoice_id description: 'The ID of the invoice.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/invoices/{invoice_id}/payments': post: summary: '' operationId: postApiV1BusinessesBusinessInvoicesInvoice_idPayments description: '' parameters: [] responses: {} tags: - 'Sales invoices' requestBody: required: true content: application/json: schema: type: object properties: amount: type: number description: 'Must not be greater than 999999999.' example: 1 method: type: string description: '' example: cash enum: - cash - bank - upi - card - cheque - other payment_account_id: type: integer description: '' example: 16 paid_on: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true reference: type: string description: 'Must not be greater than 64 characters.' example: 'n' nullable: true notes: type: string description: 'Must not be greater than 1000 characters.' example: g nullable: true required: - amount - method - payment_account_id parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: invoice_id description: 'The ID of the invoice.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/invoices/{invoice_id}/void': post: summary: 'Void an unpaid invoice that has no returns.' operationId: voidAnUnpaidInvoiceThatHasNoReturns description: 'Invoices with a payment or a sales return must be settled through the corresponding payment or return workflow and cannot be voided.' parameters: [] responses: 422: description: '' content: application/json: schema: type: object example: message: 'Only unpaid, active invoices without returns can be voided.' errors: invoice: - 'Only unpaid, active invoices without returns can be voided.' properties: message: type: string example: 'Only unpaid, active invoices without returns can be voided.' errors: type: object properties: invoice: type: array example: - 'Only unpaid, active invoices without returns can be voided.' items: type: string tags: - 'Sales invoices' requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'Must be at least 3 characters. Must not be greater than 255 characters.' example: b required: - reason parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: invoice_id description: 'The ID of the invoice.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/documents': get: summary: '' operationId: getApiV1BusinessesBusinessDocuments description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Business documents' requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: '' example: quote enum: - quote - purchase_order - purchase_invoice - recurring_invoice - sales_return - purchase_return status: type: string description: 'Must not be greater than 32 characters.' example: b nullable: true contact_id: type: integer description: '' example: 16 nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 nullable: true required: - type parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/documents/{document_type}': post: summary: '' operationId: postApiV1BusinessesBusinessDocumentsDocument_type description: '' parameters: [] responses: {} tags: - 'Business documents' requestBody: required: true content: application/json: schema: type: object properties: contact_id: type: integer description: '' example: 16 source_invoice_id: type: integer description: '' example: 16 nullable: true source_document_id: type: integer description: '' example: 16 nullable: true issue_date: type: string description: 'Must be a valid date.' example: '2026-01-15' due_date: type: string description: 'Must be a valid date. Must be a date after or equal to issue_date.' example: '2026-01-15' nullable: true frequency: type: string description: '' example: weekly enum: - weekly - monthly - quarterly - yearly nullable: true next_issue_date: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true end_date: type: string description: 'Must be a valid date. Must be a date after or equal to next_issue_date.' example: '2026-01-15' nullable: true notes: type: string description: 'Must not be greater than 2000 characters.' example: 'n' nullable: true external_reference: type: string description: 'Must not be greater than 64 characters.' example: g nullable: true place_of_supply_state_code: type: string description: 'Must be 2 characters.' example: zm nullable: true reverse_charge: type: boolean description: '' example: false prices_include_tax: type: boolean description: '' example: false lines: type: array description: 'Must have at least 1 items. Must not have more than 100 items.' example: - [] items: type: object properties: item_id: type: integer description: '' example: 16 nullable: true source_invoice_line_id: type: integer description: '' example: 16 nullable: true source_document_line_id: type: integer description: '' example: 16 nullable: true description: type: string description: 'Must not be greater than 255 characters.' example: 'Et animi quos velit et fugiat.' quantity: type: number description: 'Must not be greater than 999999.' example: 1 unit_price: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 5 tax_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 19 nullable: true cess_rate: type: number description: 'Must be at least 0. Must not be greater than 100.' example: 17 nullable: true discount: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 5 nullable: true price_includes_tax: type: boolean description: '' example: false required: - description - quantity - unit_price required: - contact_id - issue_date - lines parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: document_type description: '' example: quote|purchase_order|purchase_invoice|recurring_invoice|sales_return|purchase_return required: true schema: type: string '/api/v1/businesses/{business}/documents/{document_id}': get: summary: '' operationId: getApiV1BusinessesBusinessDocumentsDocument_id description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Business documents' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: document_id description: 'The ID of the document.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/documents/{document_id}/convert': post: summary: '' operationId: postApiV1BusinessesBusinessDocumentsDocument_idConvert description: '' parameters: [] responses: {} tags: - 'Business documents' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: document_id description: 'The ID of the document.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payments': get: summary: '' operationId: getApiV1BusinessesBusinessPayments description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Payments requestBody: required: true content: application/json: schema: type: object properties: direction: type: string description: '' example: received enum: - received - made from: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true to: type: string description: 'Must be a valid date. Must be a date after or equal to from.' example: '2026-01-15' nullable: true per_page: type: integer description: 'Must be at least 1. Must not be greater than 100.' example: 22 nullable: true required: - direction post: summary: '' operationId: postApiV1BusinessesBusinessPayments description: '' parameters: [] responses: {} tags: - Payments requestBody: required: true content: application/json: schema: type: object properties: invoice_id: type: integer description: '' example: 16 nullable: true business_document_id: type: integer description: '' example: 16 nullable: true amount: type: number description: 'Must not be greater than 999999999.' example: 22 paid_on: type: string description: 'Must be a valid date.' example: '2026-01-15' method: type: string description: '' example: cash enum: - cash - bank - upi - card - cheque - other payment_account_id: type: integer description: '' example: 16 nullable: true reference: type: string description: 'Must not be greater than 64 characters.' example: 'n' nullable: true notes: type: string description: 'Must not be greater than 1000 characters.' example: g nullable: true required: - amount - paid_on - method parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/expenses': get: summary: 'List expenses.' operationId: listExpenses description: "Search and filter business expenses. The response includes totals for the current\nresult, the current month, and the retained voided audit trail." parameters: - in: query name: q description: 'Search category, payee, or description.' example: internet required: false schema: type: string description: 'Search category, payee, or description.' example: internet nullable: true - in: query name: category description: 'Filter by an exact category.' example: Utilities required: false schema: type: string description: 'Filter by an exact category.' example: Utilities nullable: true - in: query name: payment_account_id description: 'Filter by the payment account used.' example: 9 required: false schema: type: integer description: 'Filter by the payment account used.' example: 9 nullable: true - in: query name: from description: 'Include expenses on or after this date (`YYYY-MM-DD`).' example: '2026-08-01' required: false schema: type: string description: 'Include expenses on or after this date (`YYYY-MM-DD`).' example: '2026-08-01' nullable: true - in: query name: to description: 'Include expenses on or before this date (`YYYY-MM-DD`).' example: '2026-08-31' required: false schema: type: string description: 'Include expenses on or before this date (`YYYY-MM-DD`).' example: '2026-08-31' nullable: true - in: query name: status description: 'Filter by posting status.' example: active required: false schema: type: string description: 'Filter by posting status.' example: active enum: - active - voided nullable: true - in: query name: per_page description: 'Results per page, from 1 to 100.' example: 20 required: false schema: type: integer description: 'Results per page, from 1 to 100.' example: 20 nullable: true responses: 200: description: '' content: application/json: schema: type: object example: data: - id: 41 category: Utilities payee: 'City Internet Services' amount_paise: 249900 occurred_on: '2026-08-12' payment_method: bank payment_account_id: 9 payment_account_name: 'HDFC Current Account' note: 'August internet bill for the main shop' voided_at: null void_reason: null created_at: '2026-08-12T10:30:00.000000Z' links: first: 'https://example.com/api/v1/businesses/1/expenses?page=1' last: 'https://example.com/api/v1/businesses/1/expenses?page=1' prev: null next: null meta: current_page: 1 from: 1 last_page: 1 path: 'https://example.com/api/v1/businesses/1/expenses' per_page: 20 to: 1 total: 1 summary: filtered_total_paise: 249900 month_total_paise: 384900 month_count: 3 voided_count: 1 properties: data: type: array example: - id: 41 category: Utilities payee: 'City Internet Services' amount_paise: 249900 occurred_on: '2026-08-12' payment_method: bank payment_account_id: 9 payment_account_name: 'HDFC Current Account' note: 'August internet bill for the main shop' voided_at: null void_reason: null created_at: '2026-08-12T10:30:00.000000Z' items: type: object properties: id: type: integer example: 41 category: type: string example: Utilities payee: type: string example: 'City Internet Services' amount_paise: type: integer example: 249900 occurred_on: type: string example: '2026-08-12' payment_method: type: string example: bank payment_account_id: type: integer example: 9 payment_account_name: type: string example: 'HDFC Current Account' note: type: string example: 'August internet bill for the main shop' voided_at: type: string example: null nullable: true void_reason: type: string example: null nullable: true created_at: type: string example: '2026-08-12T10:30:00.000000Z' links: type: object properties: first: type: string example: 'https://example.com/api/v1/businesses/1/expenses?page=1' last: type: string example: 'https://example.com/api/v1/businesses/1/expenses?page=1' prev: type: string example: null nullable: true next: type: string example: null nullable: true meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 1 path: type: string example: 'https://example.com/api/v1/businesses/1/expenses' per_page: type: integer example: 20 to: type: integer example: 1 total: type: integer example: 1 summary: type: object properties: filtered_total_paise: type: integer example: 249900 description: 'Total of non-voided expenses matching the current filters.' month_total_paise: type: integer example: 384900 description: 'Total of all non-voided expenses in the current calendar month.' month_count: type: integer example: 3 description: 'Count of all non-voided expenses in the current calendar month.' voided_count: type: integer example: 1 description: 'Count of all retained voided expenses.' tags: - Expenses post: summary: 'Post an expense atomically.' operationId: postAnExpenseAtomically description: 'The expense, general-ledger journal, cash-drawer movement, and audit record either all commit or all roll back.' parameters: [] responses: {} tags: - Expenses requestBody: required: true content: application/json: schema: type: object properties: category: type: string description: 'Must not be greater than 64 characters.' example: b payee: type: string description: 'Must not be greater than 128 characters.' example: 'n' nullable: true amount: type: number description: 'Must not be greater than 999999999.' example: 7 occurred_on: type: string description: 'Must be a valid date.' example: '2026-01-15' payment_method: type: string description: '' example: cash enum: - cash - bank - upi - card - other payment_account_id: type: integer description: '' example: 16 nullable: true note: type: string description: 'Must not be greater than 1000 characters.' example: 'n' idempotency_key: type: string description: 'Stable UUID used to make creation retries safe.' example: 6d61f406-f07d-482d-a284-3e06edfd7f55 nullable: true required: - category - amount - occurred_on - payment_method - note parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/expenses/{expense_id}': get: summary: '' operationId: getApiV1BusinessesBusinessExpensesExpense_id description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Expenses parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: expense_id description: 'The ID of the expense.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/expenses/{expense_id}/void': post: summary: 'Void an expense atomically.' operationId: voidAnExpenseAtomically description: 'The void marker, journal reversal, cash-drawer reversal, and audit record either all commit or all roll back.' parameters: [] responses: {} tags: - Expenses requestBody: required: true content: application/json: schema: type: object properties: reason: type: string description: 'Must be at least 3 characters. Must not be greater than 255 characters.' example: b required: - reason parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: expense_id description: 'The ID of the expense.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/pos/items': get: summary: '' operationId: getApiV1BusinessesBusinessPosItems description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - POS requestBody: required: false content: application/json: schema: type: object properties: q: type: string description: 'Must not be greater than 128 characters.' example: b nullable: true parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/pos/upi': get: summary: '' operationId: getApiV1BusinessesBusinessPosUpi description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - POS requestBody: required: true content: application/json: schema: type: object properties: amount: type: number description: 'Must not be greater than 10000000.' example: 1 payment_account_id: type: integer description: '' example: 16 nullable: true required: - amount parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/pos/carts': get: summary: 'List held POS carts for the business.' operationId: listHeldPOSCartsForTheBusiness description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - POS post: summary: 'Hold a POS cart for later checkout.' operationId: holdAPOSCartForLaterCheckout description: '' parameters: [] responses: {} tags: - POS requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: 'Must not be greater than 96 characters.' example: b contact_id: type: integer description: '' example: 16 nullable: true lines: type: array description: 'Must have at least 1 items. Must not have more than 100 items.' example: - [] items: type: object properties: item_id: type: integer description: '' example: 16 quantity: type: number description: '' example: 4326.41688 required: - item_id - quantity required: - name - lines parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/pos/checkout': post: summary: '' operationId: postApiV1BusinessesBusinessPosCheckout description: '' parameters: [] responses: {} tags: - POS requestBody: required: true content: application/json: schema: type: object properties: contact_id: type: integer description: '' example: 16 idempotency_key: type: string description: 'Must be a valid UUID.' example: a4855dc5-0acb-33c3-b921-f4291f719ca0 cart_id: type: integer description: '' example: 16 nullable: true lines: type: array description: 'Must have at least 1 items. Must not have more than 100 items.' example: - [] items: type: object properties: item_id: type: integer description: '' example: 16 quantity: type: number description: '' example: 4326.41688 discount: type: number description: 'Must be at least 0.' example: 77 nullable: true required: - item_id - quantity payments: type: array description: 'Must not have more than 4 items.' example: null items: type: object nullable: true properties: method: type: string description: '' example: cash enum: - cash - upi - card - bank - cheque payment_account_id: type: integer description: '' example: 16 nullable: true amount: type: number description: '' example: 4326.41688 required: - method - amount required: - contact_id - idempotency_key - lines parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/cash-register': get: summary: '' operationId: getApiV1BusinessesBusinessCashRegister description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Cash register' requestBody: required: false content: application/json: schema: type: object properties: cash_register_id: type: integer description: '' example: 16 nullable: true parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/cash-register/open': post: summary: '' operationId: postApiV1BusinessesBusinessCashRegisterOpen description: '' parameters: [] responses: {} tags: - 'Cash register' requestBody: required: true content: application/json: schema: type: object properties: cash_register_id: type: integer description: '' example: 16 nullable: true opening_float: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 22 required: - opening_float parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/cash-register/movements': post: summary: '' operationId: postApiV1BusinessesBusinessCashRegisterMovements description: '' parameters: [] responses: {} tags: - 'Cash register' requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: '' example: cash_in enum: - cash_in - cash_out cash_register_id: type: integer description: '' example: 16 nullable: true amount: type: number description: 'Must not be greater than 999999999.' example: 22 notes: type: string description: 'Must not be greater than 255 characters.' example: g required: - type - amount - notes parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/cash-register/close': post: summary: '' operationId: postApiV1BusinessesBusinessCashRegisterClose description: '' parameters: [] responses: {} tags: - 'Cash register' requestBody: required: true content: application/json: schema: type: object properties: counted_cash: type: number description: 'Must be at least 0. Must not be greater than 999999999.' example: 1 cash_register_id: type: integer description: '' example: 16 nullable: true closing_notes: type: string description: 'Must not be greater than 1000 characters.' example: 'n' nullable: true required: - counted_cash parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/reports': get: summary: '' operationId: getApiV1BusinessesBusinessReports description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Reports requestBody: required: false content: application/json: schema: type: object properties: from: type: string description: 'Must be a valid date.' example: '2026-01-15' nullable: true to: type: string description: 'Must be a valid date. Must be a date after or equal to from.' example: '2026-01-15' nullable: true parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance': get: summary: 'Get the compliance profile, registrations, evidence metadata and assessed obligations.' operationId: getTheComplianceProfileRegistrationsEvidenceMetadataAndAssessedObligations description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: business_id: 16 state_code: '29' profile: constitution: proprietorship masked_pan: 'ABC****34F' district: 'Bengaluru Urban' local_body: BBMP premises_type: rented supply_type: both gst_registration_status: not_registered previous_year_turnover_paise: 180000000 other_pan_turnover_paise: 25000000 employee_count: 4 contract_worker_count: 0 female_employee_count: 2 interstate_sales: false ecommerce_sales: true imports: false exports: false manufactures: false food_business: true uses_weighing_scale: true packs_or_imports_goods: false pharmacy: false serves_alcohol: false fire_risk: false pollution_activity: false reminder_days: - 90 - 60 - 30 - 7 - 0 assessment_completed_at: '2026-08-20T12:00:00+05:30' next_review_at: '2026-11-20T12:00:00+05:30' categories: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I gst_registrations: [] obligations: - id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: action_required reference_number: null issued_on: null due_on: null expires_on: null notes: null manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: [] guidance_notice: 'Guidance is generated from configurable rules and recorded business facts. Review items marked professional review and verify official sources before relying on them.' options: constitutions: proprietorship: Proprietorship partnership: 'Partnership firm' llp: 'Limited Liability Partnership' private_limited: 'Private limited company' public_limited: 'Public limited company' opc: 'One Person Company' huf: 'Hindu Undivided Family' trust_society: 'Trust / society' cooperative: 'Co-operative society' government: 'Government entity' other: Other supply_types: goods: 'Goods only' services: 'Services only' both: 'Goods and services' gst_statuses: not_assessed: 'Not assessed' not_registered: 'Not registered' pending: 'Application pending' active: 'Registered / active' suspended: Suspended cancelled: 'Cancelled / surrendered' gst_registration_types: normal: 'Normal taxpayer' composition: 'Composition taxpayer' casual: 'Casual taxable person' non_resident: 'Non-resident taxable person' isd: 'Input Service Distributor (ISD)' tds: 'Tax Deductor (TDS)' tcs: 'Tax Collector / e-commerce operator (TCS)' sez_unit: 'SEZ unit' sez_developer: 'SEZ developer' oidar: 'OIDAR / online money gaming supplier' uin: 'Unique Identity Number holder' temporary: 'Temporary registration' meta: available_categories: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I description: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' properties: data: type: object properties: business_id: type: integer example: 16 state_code: type: string example: '29' profile: type: object properties: constitution: type: string example: proprietorship masked_pan: type: string example: 'ABC****34F' district: type: string example: 'Bengaluru Urban' local_body: type: string example: BBMP premises_type: type: string example: rented supply_type: type: string example: both gst_registration_status: type: string example: not_registered previous_year_turnover_paise: type: integer example: 180000000 other_pan_turnover_paise: type: integer example: 25000000 employee_count: type: integer example: 4 contract_worker_count: type: integer example: 0 female_employee_count: type: integer example: 2 interstate_sales: type: boolean example: false ecommerce_sales: type: boolean example: true imports: type: boolean example: false exports: type: boolean example: false manufactures: type: boolean example: false food_business: type: boolean example: true uses_weighing_scale: type: boolean example: true packs_or_imports_goods: type: boolean example: false pharmacy: type: boolean example: false serves_alcohol: type: boolean example: false fire_risk: type: boolean example: false pollution_activity: type: boolean example: false reminder_days: type: array example: - 90 - 60 - 30 - 7 - 0 items: type: integer assessment_completed_at: type: string example: '2026-08-20T12:00:00+05:30' next_review_at: type: string example: '2026-11-20T12:00:00+05:30' categories: type: array example: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I items: type: object properties: id: type: integer example: 13 slug: type: string example: food-service name: type: string example: 'Restaurant, café and food service' nic_section: type: string example: I gst_registrations: type: array example: [] obligations: type: array example: - id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: action_required reference_number: null issued_on: null due_on: null expires_on: null notes: null manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: [] items: type: object properties: id: type: integer example: 81 rule_code: type: string example: fssai-registration-licence rule_version: type: integer example: 1 title: type: string example: 'FSSAI registration or food licence' applicability_reason: type: string example: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: type: string example: required obligation_type: type: string example: licence authority_name: type: string example: 'Food Safety and Standards Authority of India' source_url: type: string example: 'https://fssai.gov.in/business/registration' application_url: type: string example: 'https://foscos.fssai.gov.in/' status: type: string example: action_required reference_number: type: string example: null nullable: true issued_on: type: string example: null nullable: true due_on: type: string example: null nullable: true expires_on: type: string example: null nullable: true notes: type: string example: null nullable: true manual_override: type: boolean example: false last_assessed_at: type: string example: '2026-08-20T12:00:00+05:30' documents: type: array example: [] guidance_notice: type: string example: 'Guidance is generated from configurable rules and recorded business facts. Review items marked professional review and verify official sources before relying on them.' options: type: object properties: constitutions: type: object properties: proprietorship: type: string example: Proprietorship partnership: type: string example: 'Partnership firm' llp: type: string example: 'Limited Liability Partnership' private_limited: type: string example: 'Private limited company' public_limited: type: string example: 'Public limited company' opc: type: string example: 'One Person Company' huf: type: string example: 'Hindu Undivided Family' trust_society: type: string example: 'Trust / society' cooperative: type: string example: 'Co-operative society' government: type: string example: 'Government entity' other: type: string example: Other supply_types: type: object properties: goods: type: string example: 'Goods only' services: type: string example: 'Services only' both: type: string example: 'Goods and services' gst_statuses: type: object properties: not_assessed: type: string example: 'Not assessed' not_registered: type: string example: 'Not registered' pending: type: string example: 'Application pending' active: type: string example: 'Registered / active' suspended: type: string example: Suspended cancelled: type: string example: 'Cancelled / surrendered' gst_registration_types: type: object properties: normal: type: string example: 'Normal taxpayer' composition: type: string example: 'Composition taxpayer' casual: type: string example: 'Casual taxable person' non_resident: type: string example: 'Non-resident taxable person' isd: type: string example: 'Input Service Distributor (ISD)' tds: type: string example: 'Tax Deductor (TDS)' tcs: type: string example: 'Tax Collector / e-commerce operator (TCS)' sez_unit: type: string example: 'SEZ unit' sez_developer: type: string example: 'SEZ developer' oidar: type: string example: 'OIDAR / online money gaming supplier' uin: type: string example: 'Unique Identity Number holder' temporary: type: string example: 'Temporary registration' meta: type: object properties: available_categories: type: array example: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I description: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' items: type: object properties: id: type: integer example: 13 slug: type: string example: food-service name: type: string example: 'Restaurant, café and food service' nic_section: type: string example: I description: type: string example: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' tags: - 'Business compliance guidance' parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/profile': put: summary: 'Update business facts and immediately run the deterministic compliance assessment.' operationId: updateBusinessFactsAndImmediatelyRunTheDeterministicComplianceAssessment description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: business_id: 16 state_code: '29' profile: constitution: proprietorship masked_pan: 'ABC****34F' district: 'Bengaluru Urban' local_body: BBMP premises_type: rented supply_type: both gst_registration_status: not_registered previous_year_turnover_paise: 180000000 other_pan_turnover_paise: 25000000 employee_count: 4 contract_worker_count: 0 female_employee_count: 2 interstate_sales: false ecommerce_sales: true imports: false exports: false manufactures: false food_business: true uses_weighing_scale: true packs_or_imports_goods: false pharmacy: false serves_alcohol: false fire_risk: false pollution_activity: false reminder_days: - 90 - 60 - 30 - 7 - 0 assessment_completed_at: '2026-08-20T12:00:00+05:30' next_review_at: '2026-11-20T12:00:00+05:30' categories: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I gst_registrations: [] obligations: - id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: action_required reference_number: null issued_on: null due_on: null expires_on: null notes: null manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: [] guidance_notice: 'Guidance is generated from configurable rules and recorded business facts. Review items marked professional review and verify official sources before relying on them.' options: constitutions: proprietorship: Proprietorship partnership: 'Partnership firm' llp: 'Limited Liability Partnership' private_limited: 'Private limited company' public_limited: 'Public limited company' opc: 'One Person Company' huf: 'Hindu Undivided Family' trust_society: 'Trust / society' cooperative: 'Co-operative society' government: 'Government entity' other: Other supply_types: goods: 'Goods only' services: 'Services only' both: 'Goods and services' gst_statuses: not_assessed: 'Not assessed' not_registered: 'Not registered' pending: 'Application pending' active: 'Registered / active' suspended: Suspended cancelled: 'Cancelled / surrendered' gst_registration_types: normal: 'Normal taxpayer' composition: 'Composition taxpayer' casual: 'Casual taxable person' non_resident: 'Non-resident taxable person' isd: 'Input Service Distributor (ISD)' tds: 'Tax Deductor (TDS)' tcs: 'Tax Collector / e-commerce operator (TCS)' sez_unit: 'SEZ unit' sez_developer: 'SEZ developer' oidar: 'OIDAR / online money gaming supplier' uin: 'Unique Identity Number holder' temporary: 'Temporary registration' meta: available_categories: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I description: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' properties: data: type: object properties: business_id: type: integer example: 16 state_code: type: string example: '29' profile: type: object properties: constitution: type: string example: proprietorship masked_pan: type: string example: 'ABC****34F' district: type: string example: 'Bengaluru Urban' local_body: type: string example: BBMP premises_type: type: string example: rented supply_type: type: string example: both gst_registration_status: type: string example: not_registered previous_year_turnover_paise: type: integer example: 180000000 other_pan_turnover_paise: type: integer example: 25000000 employee_count: type: integer example: 4 contract_worker_count: type: integer example: 0 female_employee_count: type: integer example: 2 interstate_sales: type: boolean example: false ecommerce_sales: type: boolean example: true imports: type: boolean example: false exports: type: boolean example: false manufactures: type: boolean example: false food_business: type: boolean example: true uses_weighing_scale: type: boolean example: true packs_or_imports_goods: type: boolean example: false pharmacy: type: boolean example: false serves_alcohol: type: boolean example: false fire_risk: type: boolean example: false pollution_activity: type: boolean example: false reminder_days: type: array example: - 90 - 60 - 30 - 7 - 0 items: type: integer assessment_completed_at: type: string example: '2026-08-20T12:00:00+05:30' next_review_at: type: string example: '2026-11-20T12:00:00+05:30' categories: type: array example: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I items: type: object properties: id: type: integer example: 13 slug: type: string example: food-service name: type: string example: 'Restaurant, café and food service' nic_section: type: string example: I gst_registrations: type: array example: [] obligations: type: array example: - id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: action_required reference_number: null issued_on: null due_on: null expires_on: null notes: null manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: [] items: type: object properties: id: type: integer example: 81 rule_code: type: string example: fssai-registration-licence rule_version: type: integer example: 1 title: type: string example: 'FSSAI registration or food licence' applicability_reason: type: string example: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: type: string example: required obligation_type: type: string example: licence authority_name: type: string example: 'Food Safety and Standards Authority of India' source_url: type: string example: 'https://fssai.gov.in/business/registration' application_url: type: string example: 'https://foscos.fssai.gov.in/' status: type: string example: action_required reference_number: type: string example: null nullable: true issued_on: type: string example: null nullable: true due_on: type: string example: null nullable: true expires_on: type: string example: null nullable: true notes: type: string example: null nullable: true manual_override: type: boolean example: false last_assessed_at: type: string example: '2026-08-20T12:00:00+05:30' documents: type: array example: [] guidance_notice: type: string example: 'Guidance is generated from configurable rules and recorded business facts. Review items marked professional review and verify official sources before relying on them.' options: type: object properties: constitutions: type: object properties: proprietorship: type: string example: Proprietorship partnership: type: string example: 'Partnership firm' llp: type: string example: 'Limited Liability Partnership' private_limited: type: string example: 'Private limited company' public_limited: type: string example: 'Public limited company' opc: type: string example: 'One Person Company' huf: type: string example: 'Hindu Undivided Family' trust_society: type: string example: 'Trust / society' cooperative: type: string example: 'Co-operative society' government: type: string example: 'Government entity' other: type: string example: Other supply_types: type: object properties: goods: type: string example: 'Goods only' services: type: string example: 'Services only' both: type: string example: 'Goods and services' gst_statuses: type: object properties: not_assessed: type: string example: 'Not assessed' not_registered: type: string example: 'Not registered' pending: type: string example: 'Application pending' active: type: string example: 'Registered / active' suspended: type: string example: Suspended cancelled: type: string example: 'Cancelled / surrendered' gst_registration_types: type: object properties: normal: type: string example: 'Normal taxpayer' composition: type: string example: 'Composition taxpayer' casual: type: string example: 'Casual taxable person' non_resident: type: string example: 'Non-resident taxable person' isd: type: string example: 'Input Service Distributor (ISD)' tds: type: string example: 'Tax Deductor (TDS)' tcs: type: string example: 'Tax Collector / e-commerce operator (TCS)' sez_unit: type: string example: 'SEZ unit' sez_developer: type: string example: 'SEZ developer' oidar: type: string example: 'OIDAR / online money gaming supplier' uin: type: string example: 'Unique Identity Number holder' temporary: type: string example: 'Temporary registration' meta: type: object properties: available_categories: type: array example: - id: 13 slug: food-service name: 'Restaurant, café and food service' nic_section: I description: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' items: type: object properties: id: type: integer example: 13 slug: type: string example: food-service name: type: string example: 'Restaurant, café and food service' nic_section: type: string example: I description: type: string example: 'Restaurants, cafés, caterers, cloud kitchens and mobile food service.' tags: - 'Business compliance guidance' requestBody: required: true content: application/json: schema: type: object properties: state_code: type: string description: 'Two-character GST state/UT code.' example: '29' category_ids: type: array description: 'Must match an existing stored value.' example: - 13 items: type: integer constitution: type: string description: 'Legal constitution of the business.' example: proprietorship enum: - proprietorship - partnership - llp - private_limited - public_limited - opc - huf - trust_society - cooperative - government - other pan: type: string description: 'PAN. Required for a business marked not registered under GST. Omit to keep the saved PAN. Must match the regex /^[A-Z]{5}[0-9]{4}[A-Z]$/. Must be 10 characters.' example: ABCDE1234F nullable: true district: type: string description: 'District containing the principal place of business. Must not be greater than 96 characters.' example: 'Bengaluru Urban' nullable: true local_body: type: string description: 'Municipality, corporation or panchayat. Must not be greater than 128 characters.' example: BBMP nullable: true premises_type: type: string description: 'How the principal premises is occupied.' example: rented enum: - owned - rented - leased - home - mobile - virtual - other supply_type: type: string description: 'Whether the business supplies goods, services or both.' example: both enum: - goods - services - both gst_registration_status: type: string description: 'Declared GST registration status.' example: not_registered enum: - not_assessed - not_registered - pending - active - suspended - cancelled previous_year_turnover: type: number description: 'Previous financial-year PAN-wide aggregate turnover in rupees. Must be at least 0. Must not be greater than 999999999999.99.' example: 1800000 other_pan_turnover: type: number description: 'Current-year PAN-wide turnover not recorded in this workspace, in rupees. Must be at least 0. Must not be greater than 999999999999.99.' example: 250000 employee_count: type: integer description: 'Direct employee count. Must be at least 0. Must not be greater than 1000000.' example: 4 contract_worker_count: type: integer description: 'Contract worker count. Must be at least 0. Must not be greater than 1000000.' example: 0 female_employee_count: type: integer description: 'Women employees, not exceeding employee_count. Must be at least 0. Must not be greater than 1000000.' example: 2 interstate_sales: type: boolean description: '' example: false ecommerce_sales: type: boolean description: '' example: true imports: type: boolean description: '' example: false exports: type: boolean description: '' example: false manufactures: type: boolean description: '' example: false food_business: type: boolean description: '' example: true uses_weighing_scale: type: boolean description: '' example: true packs_or_imports_goods: type: boolean description: '' example: false pharmacy: type: boolean description: '' example: false serves_alcohol: type: boolean description: '' example: false fire_risk: type: boolean description: '' example: false pollution_activity: type: boolean description: '' example: false reminder_days: type: array description: 'Must be at least 0. Must not be greater than 365.' example: - 90 - 60 - 30 - 7 - 0 items: type: integer required: - state_code - category_ids - constitution - premises_type - supply_type - gst_registration_status - previous_year_turnover - other_pan_turnover - employee_count - contract_worker_count - female_employee_count - interstate_sales - ecommerce_sales - imports - exports - manufactures - food_business - uses_weighing_scale - packs_or_imports_goods - pharmacy - serves_alcohol - fire_risk - pollution_activity parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/assess': post: summary: 'Re-run assessment against the latest published rule revisions.' operationId: reRunAssessmentAgainstTheLatestPublishedRuleRevisions description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: matched: 8 closed: 1 properties: data: type: object properties: matched: type: integer example: 8 closed: type: integer example: 1 tags: - 'Business compliance guidance' parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/gst-registrations': post: summary: '' operationId: postApiV1BusinessesBusiness_idComplianceGstRegistrations description: '' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: id: 32 business_id: 16 registration_type: composition registration_status: active gstin: 29ABCDE1234F1Z5 uin: null state_code: '29' is_primary: true valid_from: '2026-04-01T00:00:00.000000Z' valid_until: null created_at: '2026-08-20T06:30:00.000000Z' updated_at: '2026-08-20T06:30:00.000000Z' properties: data: type: object properties: id: type: integer example: 32 business_id: type: integer example: 16 registration_type: type: string example: composition registration_status: type: string example: active gstin: type: string example: 29ABCDE1234F1Z5 uin: type: string example: null nullable: true state_code: type: string example: '29' is_primary: type: boolean example: true valid_from: type: string example: '2026-04-01T00:00:00.000000Z' valid_until: type: string example: null nullable: true created_at: type: string example: '2026-08-20T06:30:00.000000Z' updated_at: type: string example: '2026-08-20T06:30:00.000000Z' tags: - 'Business compliance guidance' requestBody: required: true content: application/json: schema: type: object properties: registration_type: type: string description: 'GST taxpayer/registration profile.' example: composition enum: - normal - composition - casual - non_resident - isd - tds - tcs - sez_unit - sez_developer - oidar - uin - temporary registration_status: type: string description: 'Current portal status.' example: active enum: - pending - active - suspended - cancelled gstin: type: string description: '15-character GSTIN. Required except for a UIN record. This field is required unless registration_type is in uin. Must match the regex /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/. Must be 15 characters.' example: 29ABCDE1234F1Z5 nullable: true uin: type: string description: 'Unique Identity Number for UIN records. This field is required when registration_type is uin. Must not be greater than 32 characters.' example: null nullable: true state_code: type: string description: 'Two-character state/UT code; must match the GSTIN prefix.' example: '29' nullable: true is_primary: type: boolean description: 'Whether this is the primary invoicing registration.' example: true valid_from: type: string description: 'Must be a valid date.' example: '2026-04-01' nullable: true valid_until: type: string description: 'Must be a valid date. Must be a date after or equal to valid_from.' example: null nullable: true required: - registration_type - registration_status - is_primary parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/gst-registrations/{gstRegistration_id}': delete: summary: '' operationId: deleteApiV1BusinessesBusiness_idComplianceGstRegistrationsGstRegistration_id description: '' parameters: [] responses: 204: description: '' content: application/json: schema: type: object example: {} properties: {} tags: - 'Business compliance guidance' parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer - in: path name: gstRegistration_id description: 'The ID of the gstRegistration.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/obligations/{complianceObligation_id}': get: summary: '' operationId: getApiV1BusinessesBusiness_idComplianceObligationsComplianceObligation_id description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: obtained reference_number: FSSAI-10010022000123 issued_on: '2026-04-01' due_on: null expires_on: '2027-03-31' notes: 'Certificate verified.' manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' properties: data: type: object properties: id: type: integer example: 81 rule_code: type: string example: fssai-registration-licence rule_version: type: integer example: 1 title: type: string example: 'FSSAI registration or food licence' applicability_reason: type: string example: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: type: string example: required obligation_type: type: string example: licence authority_name: type: string example: 'Food Safety and Standards Authority of India' source_url: type: string example: 'https://fssai.gov.in/business/registration' application_url: type: string example: 'https://foscos.fssai.gov.in/' status: type: string example: obtained reference_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' due_on: type: string example: null nullable: true expires_on: type: string example: '2027-03-31' notes: type: string example: 'Certificate verified.' manual_override: type: boolean example: false last_assessed_at: type: string example: '2026-08-20T12:00:00+05:30' documents: type: array example: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' items: type: object properties: id: type: integer example: 44 original_name: type: string example: fssai-certificate.pdf mime_type: type: string example: application/pdf size: type: integer example: 102400 document_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' expires_on: type: string example: '2027-03-31' is_current: type: boolean example: true download_url: type: string example: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' tags: - 'Business compliance guidance' patch: summary: '' operationId: patchApiV1BusinessesBusiness_idComplianceObligationsComplianceObligation_id description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: obtained reference_number: FSSAI-10010022000123 issued_on: '2026-04-01' due_on: null expires_on: '2027-03-31' notes: 'Certificate verified.' manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' properties: data: type: object properties: id: type: integer example: 81 rule_code: type: string example: fssai-registration-licence rule_version: type: integer example: 1 title: type: string example: 'FSSAI registration or food licence' applicability_reason: type: string example: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: type: string example: required obligation_type: type: string example: licence authority_name: type: string example: 'Food Safety and Standards Authority of India' source_url: type: string example: 'https://fssai.gov.in/business/registration' application_url: type: string example: 'https://foscos.fssai.gov.in/' status: type: string example: obtained reference_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' due_on: type: string example: null nullable: true expires_on: type: string example: '2027-03-31' notes: type: string example: 'Certificate verified.' manual_override: type: boolean example: false last_assessed_at: type: string example: '2026-08-20T12:00:00+05:30' documents: type: array example: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' items: type: object properties: id: type: integer example: 44 original_name: type: string example: fssai-certificate.pdf mime_type: type: string example: application/pdf size: type: integer example: 102400 document_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' expires_on: type: string example: '2027-03-31' is_current: type: boolean example: true download_url: type: string example: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' tags: - 'Business compliance guidance' requestBody: required: true content: application/json: schema: type: object properties: status: type: string description: 'Owner-tracked status. not_applicable requires notes.' example: obtained enum: - action_required - in_progress - obtained - not_applicable - expired - no_longer_applicable reference_number: type: string description: 'Application, registration or licence number. Must not be greater than 128 characters.' example: LIC-2026-1001 nullable: true issued_on: type: string description: 'Must be a valid date.' example: '2026-04-01' nullable: true due_on: type: string description: 'Must be a valid date.' example: null nullable: true expires_on: type: string description: 'Must be a valid date. Must be a date after or equal to issued_on.' example: '2027-03-31' nullable: true notes: type: string description: 'Must not be greater than 5000 characters.' example: 'Renewal filed by the accountant.' nullable: true required: - status parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer - in: path name: complianceObligation_id description: 'The ID of the complianceObligation.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/obligations/{complianceObligation_id}/documents': post: summary: '' operationId: postApiV1BusinessesBusiness_idComplianceObligationsComplianceObligation_idDocuments description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 81 rule_code: fssai-registration-licence rule_version: 1 title: 'FSSAI registration or food licence' applicability_reason: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: required obligation_type: licence authority_name: 'Food Safety and Standards Authority of India' source_url: 'https://fssai.gov.in/business/registration' application_url: 'https://foscos.fssai.gov.in/' status: obtained reference_number: FSSAI-10010022000123 issued_on: '2026-04-01' due_on: null expires_on: '2027-03-31' notes: 'Certificate verified.' manual_override: false last_assessed_at: '2026-08-20T12:00:00+05:30' documents: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' properties: data: type: object properties: id: type: integer example: 81 rule_code: type: string example: fssai-registration-licence rule_version: type: integer example: 1 title: type: string example: 'FSSAI registration or food licence' applicability_reason: type: string example: 'Every food business operator must hold the matching registration or licence. Matched using Guidance Shop facts.' applicability_level: type: string example: required obligation_type: type: string example: licence authority_name: type: string example: 'Food Safety and Standards Authority of India' source_url: type: string example: 'https://fssai.gov.in/business/registration' application_url: type: string example: 'https://foscos.fssai.gov.in/' status: type: string example: obtained reference_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' due_on: type: string example: null nullable: true expires_on: type: string example: '2027-03-31' notes: type: string example: 'Certificate verified.' manual_override: type: boolean example: false last_assessed_at: type: string example: '2026-08-20T12:00:00+05:30' documents: type: array example: - id: 44 original_name: fssai-certificate.pdf mime_type: application/pdf size: 102400 document_number: FSSAI-10010022000123 issued_on: '2026-04-01' expires_on: '2027-03-31' is_current: true download_url: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' items: type: object properties: id: type: integer example: 44 original_name: type: string example: fssai-certificate.pdf mime_type: type: string example: application/pdf size: type: integer example: 102400 document_number: type: string example: FSSAI-10010022000123 issued_on: type: string example: '2026-04-01' expires_on: type: string example: '2027-03-31' is_current: type: boolean example: true download_url: type: string example: 'https://billing.example.com/api/v1/businesses/16/compliance/documents/44/download' tags: - 'Business compliance guidance' requestBody: required: true content: multipart/form-data: schema: type: object properties: document: type: string format: binary description: 'Private PDF/JPEG/PNG/WebP evidence, maximum 10 MB. Must be a file. Must not be greater than 10240 kilobytes.' document_number: type: string description: 'Certificate or licence number. Must not be greater than 128 characters.' example: FSSAI-10010022000123 nullable: true issued_on: type: string description: 'Must be a valid date.' example: '2026-04-01' nullable: true expires_on: type: string description: 'Must be a valid date. Must be a date after or equal to issued_on.' example: '2027-03-31' nullable: true required: - document parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer - in: path name: complianceObligation_id description: 'The ID of the complianceObligation.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business_id}/compliance/documents/{complianceDocument_id}/download': get: summary: '' operationId: getApiV1BusinessesBusiness_idComplianceDocumentsComplianceDocument_idDownload description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Business compliance guidance' parameters: - in: path name: business_id description: 'The ID of the business.' example: 1 required: true schema: type: integer - in: path name: complianceDocument_id description: 'The ID of the complianceDocument.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/gst': get: summary: '' operationId: getApiV1BusinessesBusinessGst description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'GST compliance' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/gst/gstr1': get: summary: '' operationId: getApiV1BusinessesBusinessGstGstr1 description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'GST compliance' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/gst/gstr2b': post: summary: '' operationId: postApiV1BusinessesBusinessGstGstr2b description: '' parameters: [] responses: {} tags: - 'GST compliance' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing': get: summary: 'List plans and activation availability' operationId: listPlansAndActivationAvailability description: "Use `razorpay_checkout_enabled` for paid checkout. `paid_plan_activation_enabled` refers only to the\nsupport-only manual activation fallback, while each plan's `activation_available` covers either path." parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Billing parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/payments': get: summary: 'List subscription payments' operationId: listSubscriptionPayments description: "Returns successful subscription charges and mandate authorisations for the business owner.\nOnly captured recurring charges expose an invoice download URL." parameters: - in: query name: per_page description: 'Results per page.' example: 20 required: false schema: type: integer description: 'Results per page.' example: 20 responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Billing parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/payments/{subscriptionPayment_id}/invoice': get: summary: 'Download a subscription invoice' operationId: downloadASubscriptionInvoice description: 'Downloads the immutable PDF invoice for a captured recurring subscription charge.' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - Billing parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: subscriptionPayment_id description: 'The ID of the subscriptionPayment.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/change': post: summary: 'Change the current plan' operationId: changeTheCurrentPlan description: "Paid plans return HTTP 422 while online paid-plan activation is disabled. The free plan remains selectable.\nChanging away from a Razorpay-backed plan cancels that provider subscription immediately before the new\nplan is activated, so mobile clients must confirm an immediate loss of paid access before submitting. If\nRazorpay cannot confirm cancellation, the endpoint returns HTTP 422 and leaves the current plan unchanged." parameters: [] responses: 422: description: '' content: application/json: schema: type: object example: message: 'Online paid-plan activation is not configured. Contact support to change this plan.' errors: plan_id: - 'Online paid-plan activation is not configured. Contact support to change this plan.' properties: message: type: string example: 'Online paid-plan activation is not configured. Contact support to change this plan.' errors: type: object properties: plan_id: type: array example: - 'Online paid-plan activation is not configured. Contact support to change this plan.' items: type: string tags: - Billing requestBody: required: true content: application/json: schema: type: object properties: plan_id: type: string description: 'Must match an existing stored value.' example: architecto billing_interval: type: string description: '' example: monthly enum: - monthly - yearly required: - plan_id - billing_interval parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/checkout': post: summary: 'Start Razorpay subscription checkout' operationId: startRazorpaySubscriptionCheckout description: "Creates a price-versioned Razorpay subscription. Mobile clients must pass the returned `subscription_id`\nto Razorpay Standard Checkout and then send the signed result to the confirm endpoint." parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: checkout_id: 1 key: rzp_test_example subscription_id: sub_example name: Dukanam description: 'Smart Books · Monthly' amount_paise: 99900 currency: INR trial_days: 14 prefill: name: 'Shop Owner' email: owner@example.com contact: '9876543210' properties: data: type: object properties: checkout_id: type: integer example: 1 key: type: string example: rzp_test_example subscription_id: type: string example: sub_example name: type: string example: Dukanam description: type: string example: 'Smart Books · Monthly' amount_paise: type: integer example: 99900 currency: type: string example: INR trial_days: type: integer example: 14 prefill: type: object properties: name: type: string example: 'Shop Owner' email: type: string example: owner@example.com contact: type: string example: '9876543210' tags: - Billing requestBody: required: true content: application/json: schema: type: object properties: plan_id: type: string description: 'Must match an existing stored value.' example: architecto billing_interval: type: string description: '' example: monthly enum: - monthly - yearly required: - plan_id - billing_interval parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/checkouts/{billingCheckout_id}/confirm': post: summary: 'Confirm Razorpay subscription authorisation' operationId: confirmRazorpaySubscriptionAuthorisation description: "The server verifies the Razorpay HMAC signature and fetches provider state before granting access.\nTrial access starts only after successful payment-method authorisation; a plan without a trial waits\nfor Razorpay to report the subscription as active. When the checkout replaces another Razorpay plan,\nthe previous provider subscription is cancelled immediately before the replacement is activated." parameters: [] responses: {} tags: - Billing requestBody: required: true content: application/json: schema: type: object properties: razorpay_payment_id: type: string description: 'Must match the regex /^pay_[A-Za-z0-9]+$/. Must not be greater than 191 characters.' example: b razorpay_subscription_id: type: string description: 'Must match the regex /^sub_[A-Za-z0-9]+$/. Must not be greater than 191 characters.' example: 'n' razorpay_signature: type: string description: 'Must match the regex /^[a-f0-9]{64}$/i. Must be 64 characters.' example: gzmiyvdljnikhwaykcmyuwpwlvqwrsitcpscqldzsnrwtujwvlxjklqppwqbewtn required: - razorpay_payment_id - razorpay_subscription_id - razorpay_signature parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: billingCheckout_id description: 'The ID of the billingCheckout.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/billing/cancel': post: summary: '' operationId: postApiV1BusinessesBusinessBillingCancel description: '' parameters: [] responses: {} tags: - Billing parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/exports': get: summary: 'Export business data' operationId: exportBusinessData description: "CSV exports are intended for reporting and use `dukanam-{type}-YYYY-MM-DD.csv` filenames. The legacy\n`business-backup` type returns a `dukanam-business-export-v2` owner/admin-only customer-data portability\nexport named `dukanam-business-export-YYYY-MM-DD.json`. It includes item photos and compliance evidence\ncontent, but is not a restorable platform backup." parameters: - in: query name: type description: 'Export type.' example: invoices required: true schema: type: string description: 'Export type.' example: invoices responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Data exports' requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: '' example: contacts enum: - contacts - ledger - invoices - expenses - business-backup required: - type parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/team': get: summary: 'List team members, pending invitations, and the 25 most recent expired invitations.' operationId: listTeamMembersPendingInvitationsAndThe25MostRecentExpiredInvitations description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: members: - id: 2 name: 'Priya Rao' email: priya@example.com role: cashier status: active joined_at: '2026-08-21T12:00:00.000000Z' invitations: [] roles: cashier: label: Cashier description: 'POS, sales, and cash register access.' accountant: label: Accountant description: 'Sales, purchases, inventory, accounting, reports, compliance, and exports.' seats: used: 2 limit: 5 active: 2 pending: 0 properties: data: type: object properties: members: type: array example: - id: 2 name: 'Priya Rao' email: priya@example.com role: cashier status: active joined_at: '2026-08-21T12:00:00.000000Z' items: type: object properties: id: type: integer example: 2 name: type: string example: 'Priya Rao' email: type: string example: priya@example.com role: type: string example: cashier status: type: string example: active joined_at: type: string example: '2026-08-21T12:00:00.000000Z' invitations: type: array example: [] roles: type: object properties: cashier: type: object properties: label: type: string example: Cashier description: type: string example: 'POS, sales, and cash register access.' accountant: type: object properties: label: type: string example: Accountant description: type: string example: 'Sales, purchases, inventory, accounting, reports, compliance, and exports.' seats: type: object properties: used: type: integer example: 2 limit: type: integer example: 5 description: 'Total workspace seat limit. A value of 0 means unlimited seats.' active: type: integer example: 2 pending: type: integer example: 0 tags: - 'Team access' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/team/invitations': post: summary: 'Invite a team member.' operationId: inviteATeamMember description: 'Pending invitations reserve a seat and expire after seven days.' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: id: 12 email: cashier@example.com role: cashier status: pending expires_at: '2026-08-28T12:00:00.000000Z' accepted_at: null invited_by: id: 1 name: 'Workspace Owner' properties: data: type: object properties: id: type: integer example: 12 email: type: string example: cashier@example.com role: type: string example: cashier status: type: string example: pending expires_at: type: string example: '2026-08-28T12:00:00.000000Z' accepted_at: type: string example: null nullable: true invited_by: type: object properties: id: type: integer example: 1 name: type: string example: 'Workspace Owner' tags: - 'Team access' requestBody: required: true content: application/json: schema: type: object properties: email: type: string description: "The invited person's email." example: cashier@example.com role: type: string description: 'One of admin, manager, cashier, accountant, staff, or viewer.' example: cashier required: - email - role parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/team/invitations/{teamInvitation_id}/resend': post: summary: 'Resend a pending or expired invitation with a new secure token.' operationId: resendAPendingOrExpiredInvitationWithANewSecureToken description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 12 email: cashier@example.com role: cashier status: pending expires_at: '2026-08-28T12:00:00.000000Z' accepted_at: null invited_by: id: 1 name: 'Workspace Owner' properties: data: type: object properties: id: type: integer example: 12 email: type: string example: cashier@example.com role: type: string example: cashier status: type: string example: pending expires_at: type: string example: '2026-08-28T12:00:00.000000Z' accepted_at: type: string example: null nullable: true invited_by: type: object properties: id: type: integer example: 1 name: type: string example: 'Workspace Owner' 422: description: '' content: application/json: schema: type: object example: message: 'All 2 workspace seats are already assigned or reserved.' errors: email: - 'All 2 workspace seats are already assigned or reserved.' properties: message: type: string example: 'All 2 workspace seats are already assigned or reserved.' errors: type: object properties: email: type: array example: - 'All 2 workspace seats are already assigned or reserved.' items: type: string tags: - 'Team access' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: teamInvitation_id description: 'The ID of the teamInvitation.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/team/invitations/{teamInvitation_id}': delete: summary: 'Cancel a pending invitation and release its reserved seat.' operationId: cancelAPendingInvitationAndReleaseItsReservedSeat description: '' parameters: [] responses: 204: description: '' content: application/json: schema: type: object example: {} properties: {} 403: description: '' content: application/json: schema: type: object example: message: 'Only the owner can manage administrator invitations.' properties: message: type: string example: 'Only the owner can manage administrator invitations.' tags: - 'Team access' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: teamInvitation_id description: 'The ID of the teamInvitation.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/team/members/{member_id}': patch: summary: "Change a member's role or suspend/reactivate access." operationId: changeAMembersRoleOrSuspendreactivateAccess description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: id: 2 name: 'Priya Rao' email: priya@example.com role: manager status: active joined_at: '2026-08-21T12:00:00.000000Z' properties: data: type: object properties: id: type: integer example: 2 name: type: string example: 'Priya Rao' email: type: string example: priya@example.com role: type: string example: manager status: type: string example: active joined_at: type: string example: '2026-08-21T12:00:00.000000Z' 422: description: '' content: application/json: schema: type: object example: message: 'All 2 workspace seats are already assigned or reserved.' errors: role: - 'All 2 workspace seats are already assigned or reserved.' status: - 'All 2 workspace seats are already assigned or reserved.' properties: message: type: string example: 'All 2 workspace seats are already assigned or reserved.' errors: type: object properties: role: type: array example: - 'All 2 workspace seats are already assigned or reserved.' items: type: string status: type: array example: - 'All 2 workspace seats are already assigned or reserved.' items: type: string tags: - 'Team access' requestBody: required: true content: application/json: schema: type: object properties: role: type: string description: 'One of admin, manager, cashier, accountant, staff, or viewer.' example: manager status: type: string description: 'Either active or suspended.' example: active required: - role - status delete: summary: "Remove a member's workspace access without deleting their user account." operationId: removeAMembersWorkspaceAccessWithoutDeletingTheirUserAccount description: '' parameters: [] responses: 204: description: '' content: application/json: schema: type: object example: {} properties: {} tags: - 'Team access' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: member_id description: 'The ID of the member.' example: 1 required: true schema: type: integer '/api/v1/team-invitations/{token}/accept': post: summary: 'Accept a team invitation as an existing user.' operationId: acceptATeamInvitationAsAnExistingUser description: 'Send a valid Sanctum bearer token belonging to the invited email. This endpoint does not create a new token.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: user: id: 2 name: 'Priya Rao' email: cashier@example.com business: id: 1 name: 'Anika Stores' role: cashier properties: data: type: object properties: user: type: object properties: id: type: integer example: 2 name: type: string example: 'Priya Rao' email: type: string example: cashier@example.com business: type: object properties: id: type: integer example: 1 name: type: string example: 'Anika Stores' role: type: string example: cashier 404: description: '' content: application/json: schema: type: object example: message: 'Not Found' properties: message: type: string example: 'Not Found' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: email: - 'Sign in with the email address that received this invitation.' invitation: - 'This workspace is no longer available.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: email: type: array example: - 'Sign in with the email address that received this invitation.' items: type: string invitation: type: array example: - 'This workspace is no longer available.' items: type: string tags: - 'Team invitations' parameters: - in: path name: token description: 'The opaque token from the invitation email.' example: 4WvBr4F8Dmcx3FJkL1nEz7PcQs2Yu9Aa required: true schema: type: string '/api/v1/team-invitations/{token}': get: summary: 'Inspect a team invitation.' operationId: inspectATeamInvitation description: 'This endpoint does not require authentication. The opaque token is supplied by the invitation email.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: business: id: 1 name: 'Anika Stores' email: cashier@example.com role: cashier role_label: Cashier status: pending expires_at: '2026-08-28T12:00:00.000000Z' existing_account: false properties: data: type: object properties: business: type: object properties: id: type: integer example: 1 name: type: string example: 'Anika Stores' email: type: string example: cashier@example.com role: type: string example: cashier role_label: type: string example: Cashier status: type: string example: pending expires_at: type: string example: '2026-08-28T12:00:00.000000Z' existing_account: type: boolean example: false 404: description: '' content: application/json: schema: type: object example: message: 'Not Found' properties: message: type: string example: 'Not Found' tags: - 'Team invitations' security: [] parameters: - in: path name: token description: 'The opaque token from the invitation email.' example: 4WvBr4F8Dmcx3FJkL1nEz7PcQs2Yu9Aa required: true schema: type: string '/api/v1/team-invitations/{token}/register-and-accept': post: summary: 'Create an account and accept a team invitation.' operationId: createAnAccountAndAcceptATeamInvitation description: 'Use this unauthenticated endpoint only when the invited email does not already belong to a Dukanam user. The response includes a new Sanctum device token.' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: user: id: 2 name: 'Priya Rao' email: cashier@example.com business: id: 1 name: 'Anika Stores' role: cashier token: 1|new-mobile-token properties: data: type: object properties: user: type: object properties: id: type: integer example: 2 name: type: string example: 'Priya Rao' email: type: string example: cashier@example.com business: type: object properties: id: type: integer example: 1 name: type: string example: 'Anika Stores' role: type: string example: cashier token: type: string example: 1|new-mobile-token 403: description: '' content: application/json: schema: type: object example: message: 'Sign in as the invited user to accept this invitation.' properties: message: type: string example: 'Sign in as the invited user to accept this invitation.' 404: description: '' content: application/json: schema: type: object example: message: 'Not Found' properties: message: type: string example: 'Not Found' 422: description: '' content: application/json: schema: type: object example: message: 'This invitation has expired or is no longer available.' errors: invitation: - 'This invitation has expired or is no longer available.' properties: message: type: string example: 'This invitation has expired or is no longer available.' errors: type: object properties: invitation: type: array example: - 'This invitation has expired or is no longer available.' items: type: string tags: - 'Team invitations' requestBody: required: true content: application/json: schema: type: object properties: name: type: string description: "The new user's name." example: 'Priya Rao' password: type: string description: "The new user's password; minimum eight characters." example: secret-pass-123 device_name: type: string description: 'The name for the new API token.' example: "Priya's phone" password_confirmation: type: string description: 'Password confirmation.' example: secret-pass-123 required: - name - password - device_name - password_confirmation security: [] parameters: - in: path name: token description: 'The opaque token from the invitation email.' example: 4WvBr4F8Dmcx3FJkL1nEz7PcQs2Yu9Aa required: true schema: type: string /api/v1/webhooks/razorpay: post: summary: 'Receive Razorpay subscription events' operationId: receiveRazorpaySubscriptionEvents description: 'This public provider callback requires a valid `X-Razorpay-Signature` HMAC header and is idempotent.' parameters: - in: header name: X-Razorpay-Signature description: '' example: 'string required Razorpay webhook HMAC signature. Example: 0123456789abcdef' schema: type: string responses: 200: description: '' content: application/json: schema: type: object example: received: true properties: received: type: boolean example: true 401: description: '' content: application/json: schema: type: object example: message: 'Invalid webhook signature.' properties: message: type: string example: 'Invalid webhook signature.' tags: - 'Billing webhooks' security: [] '/api/v1/businesses/{business}/lookups': get: summary: 'Search lookup values.' operationId: searchLookupValues description: '' parameters: - in: query name: source description: 'Lookup source.' example: customers required: true schema: type: string description: 'Lookup source.' example: customers - in: query name: q description: 'Search text, up to 100 characters.' example: priya required: false schema: type: string description: 'Search text, up to 100 characters.' example: priya nullable: true - in: query name: method description: 'Payment method used to filter compatible payment accounts.' example: upi required: false schema: type: string description: 'Payment method used to filter compatible payment accounts.' example: upi nullable: true - in: query name: direction description: 'Document or account direction.' example: received required: false schema: type: string description: 'Document or account direction.' example: received nullable: true responses: 200: description: '' content: application/json: schema: type: object example: data: - value: '42' label: 'Priya Sharma' meta: 'Customer · 9876543210' attributes: type: customer phone: '9876543210' meta: source: customers query: priya has_more: false properties: data: type: array example: - value: '42' label: 'Priya Sharma' meta: 'Customer · 9876543210' attributes: type: customer phone: '9876543210' items: type: object properties: value: type: string example: '42' label: type: string example: 'Priya Sharma' meta: type: string example: 'Customer · 9876543210' attributes: type: object properties: type: type: string example: customer phone: type: string example: '9876543210' meta: type: object properties: source: type: string example: customers description: 'Lookup source used for the response.' query: type: string example: priya description: 'Normalized search query.' has_more: type: boolean example: false description: 'Whether more matching values exist beyond this response.' tags: - Lookups parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payment-accounts': get: summary: '' operationId: getApiV1BusinessesBusinessPaymentAccounts description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Payment accounts' post: summary: '' operationId: postApiV1BusinessesBusinessPaymentAccounts description: '' parameters: [] responses: {} tags: - 'Payment accounts' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payment-accounts/{paymentAccount_id}': patch: summary: '' operationId: patchApiV1BusinessesBusinessPaymentAccountsPaymentAccount_id description: '' parameters: [] responses: {} tags: - 'Payment accounts' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: paymentAccount_id description: 'The ID of the paymentAccount.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payment-accounts/transfer': post: summary: '' operationId: postApiV1BusinessesBusinessPaymentAccountsTransfer description: '' parameters: [] responses: {} tags: - 'Payment accounts' requestBody: required: true content: application/json: schema: type: object properties: from_payment_account_id: type: integer description: '' example: 16 to_payment_account_id: type: integer description: 'The value and from_payment_account_id must be different.' example: 16 amount: type: number description: '' example: 4326.41688 transferred_on: type: string description: 'Must be a valid date.' example: '2026-01-15' reference: type: string description: 'Must not be greater than 64 characters.' example: m nullable: true notes: type: string description: 'Must not be greater than 255 characters.' example: i nullable: true required: - from_payment_account_id - to_payment_account_id - amount - transferred_on parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payment-accounts/{paymentAccount_id}/reconciliation': get: summary: 'Show eligible transactions and statement-reconciliation history.' operationId: showEligibleTransactionsAndStatementReconciliationHistory description: '' parameters: [] responses: 401: description: '' content: application/json: schema: type: object example: message: Unauthenticated. properties: message: type: string example: Unauthenticated. tags: - 'Payment accounts' requestBody: required: false content: application/json: schema: type: object properties: statement_date: type: string description: 'Must be a valid date. Must be a date before or equal to today.' example: '2026-01-15' nullable: true post: summary: 'Complete and lock a statement reconciliation.' operationId: completeAndLockAStatementReconciliation description: '' parameters: [] responses: {} tags: - 'Payment accounts' requestBody: required: true content: application/json: schema: type: object properties: statement_date: type: string description: 'Must be a valid date. Must be a date before or equal to today.' example: '2026-01-15' statement_balance: type: number description: 'Must be between -999999999 and 999999999.' example: -999999998 transaction_ids: type: array description: '' example: - 16 items: type: integer notes: type: string description: 'Must not be greater than 255 characters.' example: 'n' nullable: true required: - statement_date - statement_balance parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: paymentAccount_id description: 'The ID of the paymentAccount.' example: 1 required: true schema: type: integer '/api/v1/businesses/{business}/payment-accounts/{paymentAccount_id}/reconcile/{journalLine_id}': post: summary: '' operationId: postApiV1BusinessesBusinessPaymentAccountsPaymentAccount_idReconcileJournalLine_id description: '' parameters: [] responses: {} tags: - 'Payment accounts' parameters: - in: path name: business description: 'The business.' example: 1 required: true schema: type: integer - in: path name: paymentAccount_id description: 'The ID of the paymentAccount.' example: 1 required: true schema: type: integer - in: path name: journalLine_id description: 'The ID of the journalLine.' example: 1 required: true schema: type: integer