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

# Send a render out for signature

> Push a succeeded render's PDF to the signature service as an atomic
create-and-send signing request. Provide field placements via explicit `fields`
(page + percentage coordinates) or `anchorTags` (text anchors). Pass an
`Idempotency-Key` header to make retries safe.




## OpenAPI

````yaml /openapi.yaml post /v1/signatures
openapi: 3.1.0
info:
  title: Craftkit API
  version: 1.0.0
  description: >
    The Craftkit public REST API. Design templates with typed variables, render

    PDFs asynchronously, share and track them, and send them out for digital

    signature.


    ## Authentication


    Most endpoints authenticate with a **project API key** as a bearer token:


    ```

    Authorization: Bearer ck_live_xxxxxxxxxxxxxxxx

    ```


    Keys come in `ck_live_` (production) and `ck_test_` (test) flavours. Embed

    iframe surfaces use a short-lived **embed session JWT** instead, and the

    admin provisioning endpoint uses the deployment-wide `CRAFTKIT_ADMIN_KEY`.

    Inbound webhooks (`/v1/hooks/*`) are not bearer-authed — they are verified
    by

    an HMAC signature header.


    ## Idempotency


    `POST /v1/templates/{slug}/render` and `POST /v1/signatures` accept an

    `Idempotency-Key` request header. Retrying with the same key returns the

    original resource instead of creating (and, for signatures, billing) a

    duplicate.


    ## Errors


    Application errors use a shared envelope:


    ```json

    { "error": { "code": "invalid_request", "message": "...", "issues": { } } }

    ```


    A small number of admin/embed endpoints return a flatter shape

    (`{ "error": "invalid_credentials" }`); those are documented inline.
servers:
  - url: https://api.craftkit.dev
    description: Production
security:
  - bearerApiKey: []
tags:
  - name: Templates
    description: Create, list, fetch, republish, delete templates and enqueue renders.
  - name: Renders
    description: Poll render status, download PDFs, manage shares, email, and engagement.
  - name: Signatures
    description: >-
      Send rendered PDFs out for digital signatures via the signature service
      and track status.
  - name: Webhooks
    description: Inbound webhook receivers (HMAC-authenticated, not bearer-authed).
  - name: Embed
    description: Embed session minting, catalogs, builder templates, form submission.
  - name: Admin
    description: Org provisioning (deployment admin key only).
  - name: System
    description: Health and status.
paths:
  /v1/signatures:
    post:
      tags:
        - Signatures
      summary: Send a render out for signature
      description: >
        Push a succeeded render's PDF to the signature service as an atomic

        create-and-send signing request. Provide field placements via explicit
        `fields`

        (page + percentage coordinates) or `anchorTags` (text anchors). Pass an

        `Idempotency-Key` header to make retries safe.
      operationId: createSignature
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSignatureInput'
            example:
              renderId: 3f2a1b4c-5d6e-7f80-9a1b-2c3d4e5f6071
              name: NDA for Acme
              recipients:
                - firstName: Jane
                  lastName: Doe
                  email: jane@example.com
                  designation: Signer
              anchorTags:
                - anchorString: '{{sign_here}}'
                  type: signature
                  recipientIndex: 0
              expirationHours: 168
      responses:
        '200':
          description: Idempotent replay of an existing signature request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignatureRequest'
        '201':
          description: Signing request created and sent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignatureRequest'
              example:
                id: 5e4d3c2b-1a0f-9e8d-7c6b-5a4938271605
                renderId: 3f2a1b4c-5d6e-7f80-9a1b-2c3d4e5f6071
                name: NDA for Acme
                status: sent
                recipients:
                  - id: temp_1
                    firstName: Jane
                    lastName: Doe
                    email: jane@example.com
                    designation: Signer
                    order: 1
                expirationHours: 168
                signedDownloadUrl: null
                certificateUrl: null
                errorMessage: null
                createdAt: '2026-06-21T10:00:00.000Z'
                completedAt: null
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          description: Signature service account is out of credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: signature_credits_exhausted
                  message: The signature service account is out of credits.
        '404':
          $ref: '#/components/responses/RenderNotFound'
        '409':
          description: Render is not ready for signing (not succeeded).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: conflict
                  message: 'Render is not ready for signing (status: rendering).'
        '413':
          description: Rendered PDF exceeds the 20MB signing limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: document_too_large
                  message: Rendered PDF exceeds the 20MB signing limit.
        '502':
          description: Signature service rejected the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: signature_provider_error
                  message: 'Signature service rejected the request: ...'
        '503':
          description: Digital signatures are not configured on this server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error:
                  code: signatures_unavailable
                  message: Digital signatures are not configured on this server.
      security:
        - bearerApiKey: []
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Make retries safe — a repeated request with the same key returns the
        original resource.
      schema:
        type: string
  schemas:
    CreateSignatureInput:
      type: object
      required:
        - renderId
        - recipients
      description: |
        At least one field or anchorTag is required when any recipient is a
        Signer. recipientIndex values must be in range; supplied recipient order
        values must be a clean 1..N permutation.
      properties:
        renderId:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 255
        recipients:
          type: array
          minItems: 1
          maxItems: 20
          items:
            $ref: '#/components/schemas/SignatureRecipientInput'
        fields:
          type: array
          maxItems: 200
          items:
            $ref: '#/components/schemas/SignatureField'
        anchorTags:
          type: array
          maxItems: 200
          items:
            $ref: '#/components/schemas/SignatureAnchorTag'
        expirationHours:
          type: integer
          minimum: 1
          maximum: 8760
    SignatureRequest:
      type: object
      required:
        - id
        - renderId
        - name
        - status
        - recipients
        - expirationHours
        - signedDownloadUrl
        - certificateUrl
        - errorMessage
        - createdAt
        - completedAt
      properties:
        id:
          type: string
          format: uuid
        renderId:
          type: string
          format: uuid
        name:
          type: string
        status:
          type: string
          enum:
            - sent
            - viewed
            - completed
            - declined
            - expired
            - cancelled
            - failed
        recipients:
          type: array
          items:
            $ref: '#/components/schemas/SignatureRecipient'
        expirationHours:
          type:
            - integer
            - 'null'
        signedDownloadUrl:
          type:
            - string
            - 'null'
          format: uri
          description: Authenticated download URL; null until the signed PDF is archived.
        certificateUrl:
          type:
            - string
            - 'null'
          format: uri
          description: |
            Craftkit-owned authenticated URL (`/v1/signatures/{id}/certificate`)
            for the completion certificate; null until it is available. Not a
            provider URL.
        errorMessage:
          type:
            - string
            - 'null'
        createdAt:
          type: string
          format: date-time
        completedAt:
          type:
            - string
            - 'null'
          format: date-time
    Error:
      type: object
      description: Shared application error envelope.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
            message:
              type: string
            issues:
              description: Optional Zod flatten() / issues detail.
      example:
        error:
          code: invalid_request
          message: Request body did not match expected shape.
    SignatureRecipientInput:
      type: object
      required:
        - firstName
        - email
      properties:
        firstName:
          type: string
          minLength: 1
          maxLength: 100
        lastName:
          type: string
          maxLength: 100
        email:
          type: string
          format: email
          maxLength: 255
        designation:
          type: string
          enum:
            - Signer
            - Approver
            - CC
          default: Signer
        order:
          type: integer
          minimum: 1
    SignatureField:
      type: object
      required:
        - recipientIndex
        - type
        - page
        - x
        - 'y'
      properties:
        recipientIndex:
          type: integer
          minimum: 0
          description: 0-based index into recipients.
        type:
          type: string
          enum:
            - signature
            - initial
            - text
            - date
            - checkbox
            - dropdown
            - radio_buttons
            - text_area
        page:
          type: integer
          minimum: 1
        x:
          type: number
          minimum: 0
          maximum: 100
          description: Percentage of page width (origin top-left).
        'y':
          type: number
          minimum: 0
          maximum: 100
          description: Percentage of page height (origin top-left).
        width:
          type: number
          maximum: 100
        height:
          type: number
          maximum: 100
        required:
          type: boolean
    SignatureAnchorTag:
      type: object
      required:
        - anchorString
        - type
        - recipientIndex
      properties:
        anchorString:
          type: string
          minLength: 1
          maxLength: 200
        type:
          type: string
          enum:
            - signature
            - initials
            - text
            - date
            - checkbox
          description: Anchor-tag vocabulary uses 'initials' (not 'initial').
        recipientIndex:
          type: integer
          minimum: 0
        width:
          type: number
          maximum: 1000
          description: Offset in points relative to matched text (not a page percentage).
        height:
          type: number
          maximum: 1000
        required:
          type: boolean
        ignoreIfNotPresent:
          type: boolean
    SignatureRecipient:
      type: object
      required:
        - id
        - firstName
        - email
        - designation
      properties:
        id:
          type: string
        firstName:
          type: string
        lastName:
          type:
            - string
            - 'null'
        email:
          type: string
          format: email
        designation:
          type: string
          enum:
            - Signer
            - Approver
            - CC
        order:
          type:
            - integer
            - 'null'
        signedAt:
          type:
            - string
            - 'null'
          format: date-time
        declinedAt:
          type:
            - string
            - 'null'
          format: date-time
  responses:
    BadRequest:
      description: Invalid JSON or request shape.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: invalid_request
              message: Request body did not match expected shape.
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Missing Bearer token.
    RenderNotFound:
      description: Render not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: not_found
              message: Render not found.
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      description: >
        Project API key (`ck_live_…` or `ck_test_…`) presented as a bearer
        token.

        For embed partner endpoints this is the partner secret key, which is the

        same credential type.

````