Kamai Blueprints / Actions API

Upload a PDF. Use `upload/init`, then `PUT` the file, then `upload/complete` for anything large; `upload` sends the file in one request.

GitHub OpenAPI

Operations 3

POST /v1/blueprints/upload Upload a PDF in one request #
POST /v1/blueprints/upload/init Start an upload: get a signed URL #
POST /v1/blueprints/upload/complete Finish an upload and start reading it #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/kamai-io:kamai-io-blueprints-actions-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

kamai-io-blueprints-actions-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Kamai Blueprints / Actions API
  description: 'Read construction drawings from your own software. Upload a PDF plan; Kamai reads it and gives you back every room, wall,

    door and window with measurements in metres, every printed word, and every printed table (schedules, legends, revision

    blocks), as JSON. ## Authentication


    Create an API key at Kamai → Settings → API keys and send it on every request:


    ```

    Authorization: Bearer

    ```


    A key acts as the user who created it and sees only that user''s projects. Keep it on your server. A call without a key,

    or with a revoked one, gets `401`. Revoking a key, or a change Kamai makes to its settings, takes effect within 3 minutes. ## Acting for your users


    A partner whose users sign in through it can use any API key to act for those users. The request carries, next to the

    key, `X-Kamai-Partner` (your partner ID, as Kamai gave it to you) and `X-Kamai-Partner-User-Token` (that user''s own token

    from you). Kamai checks the token with you and acts as that user: that user''s projects, that user''s page quota, as if the

    user did it in Kamai. Without the two headers the key acts as its own owner. One header without the other is `400`

    (`partner_id_required`, `partner_user_token_required`). A user who does not exist in Kamai or is disabled gets `403`

    (`act_as_not_allowed`). A key Kamai has tied to one partner always needs both headers and never acts as its owner. What the key may do for a user is set by Kamai on the key:


    | | routes | needs |

    |---|---|---|

    | read | every `GET`, and `POST /v1/blueprints/{blueprint_id}/markups/clip` | the key enabled for partner users |

    | change | create and update projects, upload, update sheets, create and update markups, rename conversations | edit enabled |

    | delete | delete projects, jobs, markups and conversations, cancel jobs | delete enabled, separately from edit |


    A route the key may not use gets `403` (`edit_not_allowed`, `delete_not_allowed`). On every key, not only for partner users, renaming a conversation needs edit enabled and deleting one needs delete enabled; a new key has both off. Replacing a sheet''s features with

    `PUT /v1/blueprints/{blueprint_id}` for a user needs the `revision` you read as `base_revision` (`422`

    `base_revision_required`), and replacing them with none counts as a delete. Conversations work the same way;

    with edit enabled for the key, the assistant may change the user''s drawings and undo that user''s own changes; keys

    without it never write. Uploads count against the user''s own page quota. Kamai keeps the answer of each token check for up to 60 seconds, so a user you disable on your side can still be served

    for that long. ## The usual flow


    1. `POST /v1/blueprints/upload/init` returns a signed URL. 2. `PUT` the PDF to that URL. 3. `POST /v1/blueprints/upload/complete` returns a `job_id`. It starts one job per upload: calling it again with the

    same `file_uuid` returns the same `job_id` (`409` with `Retry-After` while the first call is still running). To send

    another file, start a new upload with `init`. 4. Poll `GET /v1/projects/{project_id}/jobs/{job_id}` every 5–10 s until `status` is final: `SUCCEEDED`, or

    `FAILED` / `CANCELLED` / `ABANDONED`, which end the job; for those, show `error_code` and `error_message`. The PDF check fails a job with `pdf_incomplete` (the file looks cut off or damaged: download or export it again),

    `pdf_filter_unsupported` (Brotli compression, or a PDF that cannot be read) or `pdf_scan_over_budget` (too large or

    complex to check). New `error_code` values can be added over time: treat one you do not know as a failure and show

    its `error_message`. The job record is written when processing starts, not when the upload returns, and when many uploads are queued that

    can take minutes. Until then, a `job_id` you got from an upload answers `404` with `detail` `Job not found`: keep

    polling it. `Project not found` is final. 5. On `SUCCEEDED`, read the sheet with `GET /v1/blueprints/{blueprint_id}`.'
  version: 0.1.0
tags:
- name: Blueprints / Actions
  description: Upload a PDF. Use `upload/init`, then `PUT` the file, then `upload/complete` for anything large; `upload` sends the file in one request.
paths:
  /v1/blueprints/upload:
    post:
      tags:
      - Blueprints / Actions
      summary: Upload a PDF in one request
      description: 'Upload a blueprint file directly in the request body.


        Suitable for smaller files. For large files, use the two-step

        `/upload/init` + `/upload/complete` flow instead.'
      operationId: upload_blueprint_v1_blueprints_upload_post
      security:
      - HTTPBearer: []
      parameters:
      - name: project_id
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Target project ID. When omitted, the user's Default Project is used or created.
          title: Project Id
        description: Target project ID. When omitted, the user's Default Project is used or created.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/Body_upload_blueprint_v1_blueprints_upload_post'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadBlueprintResponse'
              examples:
                real:
                  summary: Reading started
                  description: Real response shape from a Kamai test account, 2026-10-13 (one 1-page PDF on the dev lane). Ids are illustrative. Taken from upload/complete, which returns the same model.
                  value:
                    job_id: cccccccc-0000-4000-8000-000000000001
                    upload_id: dddddddd-0000-4000-8000-000000000001
                    project_id: aaaa00000004
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
  /v1/blueprints/upload/init:
    post:
      tags:
      - Blueprints / Actions
      summary: 'Start an upload: get a signed URL'
      description: 'Step 1 of the two-step upload: request a pre-signed URL for a blueprint.


        Upload the file with an HTTP PUT to the returned `signed_url`, sending exactly

        the headers in `required_headers`, then call `/upload/complete` with the

        returned `file_uuid`. Recommended for large files.'
      operationId: init_blueprint_upload_v1_blueprints_upload_init_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitUploadRequest'
            examples:
              real:
                summary: A PDF into a project
                value:
                  project_id: aaaa00000004
                  filename: A-101 Ground floor.pdf
                  mime_type: application/pdf
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InitUploadResponse'
              examples:
                real:
                  summary: Signed URL to PUT the file to
                  description: Real response shape from a Kamai test account, 2026-10-13. Names, text and ids are illustrative; numbers and structure are as returned. Signature cut.
                  value:
                    file_uuid: eeeeeeee000040008000000000000001
                    user_id: u_exampleUser00000000001
                    project_id: aaaa00000004
                    signed_url: https://storage.googleapis.com/example-bucket/signed_url_uploads/eeeeeeee000040008000000000000001?X-Goog-Algorithm=…&X-Goog-Signature=…
                    method: PUT
                    expires_in: 3600
                    required_headers:
                      Content-Type: application/pdf
                      x-goog-meta-userid: u_exampleUser00000000001
                      x-goog-meta-projectid: aaaa00000004
                      x-goog-meta-filename: A-101%20Ground%20floor.pdf
                      x-goog-meta-uploadedvia: external_api
                      x-goog-content-length-range: 0,209715200
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - HTTPBearer: []
  /v1/blueprints/upload/complete:
    post:
      tags:
      - Blueprints / Actions
      summary: Finish an upload and start reading it
      description: 'Step 2 of the two-step upload: finalize the uploaded file and start processing.'
      operationId: complete_blueprint_upload_v1_blueprints_upload_complete_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompleteUploadRequest'
            examples:
              real:
                summary: The file_uuid from init
                value:
                  file_uuid: eeeeeeee000040008000000000000001
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadBlueprintResponse'
              examples:
                real:
                  summary: Reading started
                  description: Real response shape from a Kamai test account, 2026-10-13 (one 1-page PDF on the dev lane). Ids are illustrative.
                  value:
                    job_id: cccccccc-0000-4000-8000-000000000001
                    upload_id: dddddddd-0000-4000-8000-000000000001
                    project_id: aaaa00000004
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
      - HTTPBearer: []
components:
  schemas:
    CompleteUploadRequest:
      properties:
        file_uuid:
          type: string
          title: File Uuid
          description: The file_uuid returned by /upload/init.
      type: object
      required:
      - file_uuid
      title: CompleteUploadRequest
    InitUploadResponse:
      properties:
        file_uuid:
          type: string
          title: File Uuid
          description: Identifier for this pending upload; pass it to /upload/complete.
        user_id:
          type: string
          title: User Id
          description: Authenticated user ID.
        project_id:
          type: string
          title: Project Id
          description: Resolved project ID.
        signed_url:
          type: string
          title: Signed Url
          description: Pre-signed URL. Upload the file here with an HTTP PUT.
        method:
          type: string
          title: Method
          description: HTTP method to use against signed_url.
          default: PUT
        expires_in:
          type: integer
          title: Expires In
          description: Seconds until the signed URL expires.
        required_headers:
          additionalProperties:
            type: string
          type: object
          title: Required Headers
          description: Exact headers the client MUST send on the PUT (the signature enforces them).
      type: object
      required:
      - file_uuid
      - user_id
      - project_id
      - signed_url
      - expires_in
      - required_headers
      title: InitUploadResponse
    UploadBlueprintResponse:
      properties:
        job_id:
          type: string
          format: uuid
          title: Job Id
          description: Unique identifier for the job
        upload_id:
          anyOf:
          - type: string
            format: uuid
          - type: 'null'
          title: Upload Id
          description: Identifier of the whole upload (all pages of the file)
        project_id:
          type: string
          title: Project Id
          description: Project ID used for the upload
      type: object
      required:
      - job_id
      - project_id
      title: UploadBlueprintResponse
    Body_upload_blueprint_v1_blueprints_upload_post:
      properties:
        file:
          type: string
          format: binary
          title: File
          description: Blueprint file to upload
      type: object
      required:
      - file
      title: Body_upload_blueprint_v1_blueprints_upload_post
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    InitUploadRequest:
      properties:
        project_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Project Id
          description: Target project ID. When omitted, the user's Default Project is used or created.
        filename:
          anyOf:
          - type: string
          - type: 'null'
          title: Filename
          description: Desired filename. When omitted, a UTC-timestamped default is used. Sanitized server-side.
        mime_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Mime Type
          description: File MIME type. Defaults to application/pdf; only application/pdf is allowed for now.
        size_bytes:
          anyOf:
          - type: integer
            minimum: 0.0
          - type: 'null'
          title: Size Bytes
          description: 'File size in bytes. When given and over the limit, init answers 413 before anything is signed: storage refuses an oversized PUT only after the whole body has arrived.'
      type: object
      title: InitUploadRequest
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer