> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sync2books.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Pull supplier invoices from KRA

> Fetches the supplier invoices KRA holds for the business and stores them, branch by branch. The response says how each branch went. Pulling again never changes an invoice's review status. If KRA returns nothing for every branch (all of them fail) the call is a `502` that carries the same per-branch report. The body is optional.

Required scope: `purchases:read`.



## OpenAPI

````yaml /openapi/etims.json post /v1/purchases/pull
openapi: 3.1.0
info:
  title: Sync2Books Compliance API (eTIMS)
  version: 1.0.0
  description: >-
    Register items, issue sales and credit notes, record stock and read supplier
    invoices for a Kenyan business, with every fiscal document signed by KRA
    eTIMS.


    Authenticate with an API key from the compliance dashboard, sent in the
    `x-api-key` header or as a bearer token. A `cmp_sk_test_...` key acts on
    sandbox businesses and a `cmp_sk_live_...` key on production ones; both use
    the same base URL.


    New here? Start with the [eTIMS quickstart](/etims-quickstart). The
    conventions every endpoint shares are in [Authentication & API
    keys](/etims-authentication), [Errors & Troubleshooting](/etims-errors),
    [Idempotency](/etims-idempotency) and [Rate limits](/etims-rate-limits).


    This is a separate product from the [Accounting API](/api-reference), with
    its own keys.
servers:
  - url: https://sync2books-compliance-api.apps.kintro.money
    description: >-
      Sync2Books Compliance API. The key you use decides whether a call reaches
      the KRA sandbox or production.
security:
  - ApiKeyAuth: []
  - BearerAuth: []
tags:
  - name: Identity
    description: Check what a key can do.
  - name: Businesses
    description: The businesses and branches a key can act for.
  - name: Items
    description: >-
      Create items and register them with KRA. An item must be registered before
      it can be sold.
  - name: Stock
    description: Record stock movements and report them to KRA.
  - name: Sales
    description: Issue sales, read them back and download KRA-signed receipts.
  - name: Credit notes
    description: Reverse an accepted sale in full.
  - name: Purchases
    description: Supplier invoices KRA holds against the business.
  - name: Lookups
    description: KRA code lists and item classifications.
paths:
  /v1/purchases/pull:
    post:
      tags:
        - Purchases
      summary: Pull supplier invoices from KRA
      description: >-
        Fetches the supplier invoices KRA holds for the business and stores
        them, branch by branch. The response says how each branch went. Pulling
        again never changes an invoice's review status. If KRA returns nothing
        for every branch (all of them fail) the call is a `502` that carries the
        same per-branch report. The body is optional.


        Required scope: `purchases:read`.
      operationId: pullPurchases
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PullPurchasesRequest'
            example: {}
      responses:
        '200':
          description: KRA answered for at least one branch.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    type: object
                    properties:
                      fetched:
                        type: integer
                      branches:
                        type: array
                        items:
                          $ref: '#/components/schemas/PurchasePullBranch'
              example:
                data:
                  fetched: 3
                  branches:
                    - branchId: br_example_1
                      kraBhfId: '00'
                      displayName: Head Office
                      status: ok
                      fetched: 3
                      error: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          description: KRA did not return purchases for any branch.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                upstream_error:
                  summary: upstream_error
                  value:
                    error:
                      code: upstream_error
                      message: >-
                        KRA did not return purchases for any branch. Try again
                        shortly.
                      branches:
                        - branchId: br_example_1
                          kraBhfId: '00'
                          displayName: Head Office
                          status: failed
                          fetched: 0
                          error: No response from KRA
components:
  schemas:
    PullPurchasesRequest:
      type: object
      properties:
        branchId:
          type: string
          description: Pull for one branch only. Defaults to every branch of the business.
        businessId:
          type: string
          description: >-
            The business to act for. Required for organisation-wide keys; omit
            it for a business-bound key. List the ids you can use with `GET
            /v1/businesses`.
    PurchasePullBranch:
      type: object
      properties:
        branchId:
          type: string
        kraBhfId:
          type:
            - string
            - 'null'
        displayName:
          type:
            - string
            - 'null'
        status:
          type: string
          enum:
            - ok
            - failed
        fetched:
          type: integer
          description: Invoices KRA returned for this branch. `0` when the branch failed.
        error:
          type:
            - string
            - 'null'
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          additionalProperties: true
          properties:
            code:
              type: string
              description: >-
                A stable, machine-readable code. Branch on this. See [Errors &
                Troubleshooting](/etims-errors) for the full list.
              examples:
                - invalid_request
                - kra_rejected
                - already_credited
            message:
              type: string
              description: >-
                A human-readable explanation. The wording can change; do not
                parse it.
          description: >-
            Some errors carry extra fields next to `code` and `message`, for
            example `sale`, `item`, `errors`, `creditNoteId` or `branches`.
  headers:
    RateLimitLimit:
      description: Requests allowed per minute for your application.
      schema:
        type: integer
    RateLimitRemaining:
      description: Requests left in the current one-minute window.
      schema:
        type: integer
    RateLimitReset:
      description: >-
        Seconds until the current window resets. This is a number of seconds,
        not a Unix timestamp.
      schema:
        type: integer
  responses:
    BadRequest:
      description: >-
        The request is malformed. The message names the first field that is
        wrong.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalid_request:
              summary: invalid_request
              value:
                error:
                  code: invalid_request
                  message: lines[0].quantity must be greater than 0
    Unauthorized:
      description: >-
        The key is missing, malformed, revoked, expired or belongs to a
        suspended application. The response never says which.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            invalid_api_key:
              summary: invalid_api_key
              value:
                error:
                  code: invalid_api_key
                  message: Invalid API key
    Forbidden:
      description: >-
        The key is valid but may not do this: a missing scope, a business the
        key is not limited to, or a test key used against a production business
        (or the reverse).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missing_scope:
              summary: missing_scope
              value:
                error:
                  code: forbidden
                  message: This API key is missing the sales:write scope
            other_business:
              summary: other_business
              value:
                error:
                  code: forbidden
                  message: >-
                    This API key is limited to a single business and cannot act
                    for another one.
            environment_mismatch:
              summary: environment_mismatch
              value:
                error:
                  code: forbidden
                  message: >-
                    This is a test API key and Example Business Ltd is a
                    production business. Use the key for that environment.
    NotFound:
      description: >-
        The id does not exist, or belongs to another business. The two cases are
        deliberately indistinguishable.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            not_found:
              summary: not_found
              value:
                error:
                  code: not_found
                  message: Sale sale_example_9 not found
    RateLimited:
      description: >-
        The application has used its requests for this minute. Wait
        `Retry-After` seconds.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          description: Seconds to wait before trying again.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            rate_limited:
              summary: rate_limited
              value:
                error:
                  code: rate_limited
                  message: >-
                    Rate limit of 120 requests per minute exceeded. Retry in
                    23s.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your API key, for example `cmp_sk_test_xxxxxxxxxxxxxxxxxxxxxxxx`. Create
        one on the Integrations page of the compliance dashboard.
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: cmp_sk_...
      description: >-
        The same key, sent as `Authorization: Bearer <key>`. Use this if your
        HTTP client makes custom headers awkward.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.