openapi: 3.0.1
info:
  title: Blueink API v2
  version: 2.16.0
  description: |
    # Overview

    This document contains the detailed specification for version 2 of the Blueink eSignature API.
    If just starting with the Blueink API, you might want to checkout the How-to Guides
    and Guides that supplement this API specification.

    :::warning Try it sends live requests

    The interactive **Try it** panel sends real requests to the production API
    (`https://api.blueink.com`). Requests can create billable, legally-binding
    signature records and send real emails to signers. Use a test or restricted
    API key, and never run mutating endpoints unless you intend the side effects.

    :::
servers:
  - url: https://api.blueink.com/api/v2
    description: >
      Production. This is the live API — requests sent from the interactive "Try it" panel are real and may create
      billable, legally-binding records.
security:
  - ApiKeyAuth: []
tags:
  - name: Bundles
    description: |
      A Bundle is the central object in the Blueink API — it represents one or more
      Documents being sent to one or more Signers in a single signing workflow. When
      a Bundle is created, it is launched immediately, sending the documents to the
      signers for signature.

      **Related guides:**
      [Send an Envelope with an Uploaded PDF File](/docs/guides/send-envelope-with-uploaded-pdf/) ·
      [Send an Envelope with Templates](/docs/guides/send-envelope-with-templates/) ·
      [Generate PDFs from HTML](/docs/guides/html-to-pdf/) ·
      [Auto Field Placement](/docs/guides/auto-placement/)
  - name: Packet
    description: |
      A Packet represents a single Signer's relationship to a Bundle — their assigned
      fields, their place in the signing order, the URL they receive, and their signing
      status. Packets are created automatically as part of Bundle creation; this section
      covers retrieving and updating individual Packets after the Bundle is sent,
      including generating embedded signing URLs and resending notifications.

      **Related guides:** [Implement Embedded Signing](/docs/guides/embedded-signing/)
  - name: Templates
    description: |
      A Document Template is a reusable PDF document with predefined field positions
      and signer roles. Document Templates let you create Bundles from a known shape
      without re-uploading the PDF or re-placing fields each time.

      **Related guides:** [Send an Envelope with Templates](/docs/guides/send-envelope-with-templates/)
  - name: Envelope Templates
    description: |
      An Envelope Template is a reusable Bundle definition — one or more Documents,
      a defined set of Signer roles, and any default settings — that can be instantiated
      by providing only the runtime values (signer names, emails, etc.). Use these when
      the same multi-document workflow is sent repeatedly. Bundles are created from
      Envelope Templates via the
      [Create a Bundle from an Envelope Template](/docs/api/create-bundle-from-envelope-template)
      endpoint.
  - name: Person
    description: |
      A Person is a saved contact in your Blueink account. Persons can be referenced
      as signers when creating a Bundle, eliminating the need to re-enter contact
      information for repeat recipients.
  - name: Webhook
    description: |
      Webhooks let your application receive real-time notifications when events occur
      in your Blueink account, such as a Bundle being completed or a Signer viewing a
      document. Each Webhook subscribes to one or more event types and is delivered as
      an HTTP POST to a URL you specify.

      **Related guides:** [Webhooks](/docs/esignature-api/webhook/)
  - name: WebhookEvent
    description: |
      A WebhookEvent represents a single event that occurred in your account and the
      record of its delivery attempts to subscribed Webhooks. Use this section to inspect
      past events and their delivery status, including any retried or failed deliveries.
  - name: WebhookExtraHeader
    description: |
      WebhookExtraHeaders are custom HTTP headers that Blueink will include when
      delivering events to a Webhook. Common uses include attaching a shared secret or
      bearer token so your receiver can authenticate the incoming request as originating
      from Blueink.
  - name: WebhookSecret
    description: |
      A WebhookSecret is a shared secret that Blueink uses to sign Webhook payloads. Your
      receiver verifies the signature on incoming requests to confirm that the payload
      originated from Blueink and was not tampered with in transit.
  - name: Rate Limiting
    description: |
      The Blueink API enforces rate limits per API key. Use this endpoint to inspect
      your current rate-limit status (limit, remaining requests, reset time) without
      consuming a request against another endpoint.
  - name: Verification
    description: |
      Public, unauthenticated endpoint for verifying that a PDF was produced and
      signed through Blueink. Submit the SHA-256 hash of a PDF file; Blueink checks
      whether it matches any signed PDF, combined PDF, or Certificate of Execution
      associated with a completed Bundle.
paths:
  /bundles/:
    get:
      summary: List Bundles
      description: |
        Returns a paginated list of Bundles in your Account, ordered by created date (from most recent to
        least recent). Pagination can be controlled via Pagination paramaters (see Overview->Pagination).
        Querystring filters paramaters can be combined, e.g.
        `/bundles/?search=Gibbons&status__in=se,co&tag=needs-attention`. When combining filters, only Bundles
        matching ALL the filters are returned.
      operationId: listBundles
      tags:
        - Bundles
      parameters:
        - name: search
          in: query
          description: |
            A search query. Only bundles matching the search will be returned. The following data in the
            the Bundle is searched:

            - bundle slug
            - bundle label
            - bundle custom_key
            - signer name
            - signer email
            - signer phones

            E.g. `/bundles/?search=foobar@example.com`
          required: false
          schema:
            type: string
        - name: status
          in: query
          description: |
            Limit bundles to those with the specified status.

            * ne: New - the Bundle was newly created
            * dr: Draft - the Bundle has not yet been sent
            * pr: Provisioning - the Bundle is being cloned or processed in the background
            * pe: Pending - the Bundle is queued to be launched while documents are processing
            * se: Sent - the Bundle has been sent, but not yet started by any Signers
            * st: Started - at least one Signer has started reviewing the document(s)
            * co: Complete - all Signers have completed reviewing / signing
            * ca: Cancelled - the Bundle was cancelled
            * ex: Expired - the Bundle expired before it was Complete
            * fa: Failed - an error occurred and the Bundle could not be created or completed
            * de: Declined - at least one Signer declined to sign

            E.g. `/bundles/?status=co`
          required: false
          schema:
            type: string
            enum:
              - ne
              - dr
              - pr
              - pe
              - se
              - st
              - de
              - ca
              - ex
              - fa
              - co
        - name: status__in
          in: query
          description: |
            Limit bundles to those with one of the specified statuses. Statuses should be comma separated.
            E.g. `/bundles/?status=co,se,st`
          required: false
          schema:
            type: string
            enum:
              - ne
              - dr
              - pr
              - pe
              - se
              - st
              - de
              - ca
              - ex
              - fa
              - co
        - name: tag
          in: query
          description: Return Bundles that have the given tag. E.g. `/bundles/?tag=some-tag`
          required: false
          schema:
            type: string
        - name: tag__in
          in: query
          description: |
            Return Bundles that have at least one of the given tags. Tags should be comma separated.
            E.g. `/bundles/?tag=some-tag,another-tag`
          required: false
          schema:
            type: string
        - name: ordering
          in: query
          description: |
            Control the sort order of Bundles. Prefix with "-" to reverse the sort order.
            By default Bundles are sorted by "-created", ie the Bundle creation date from most
            to least recent.
          required: false
          schema:
            type: string
            enum:
              - created
              - sent
              - completed_at
        - name: created
          in: query
          description: |
            Retrieve Bundles created within a specified date range
            Note: Dates are expressed as YYYY-MM-DD format.

            E.g. `/bundles/?created_after=2024-10-01&created_before=2024-10-08`
          required: false
          schema:
            type: string
            format: date-time
        - name: sent
          in: query
          description: |
            E.g. `/bundles/?sent_after=2024-10-01&sent_before=2024-10-08`
          required: false
          schema:
            type: string
            format: date-time
        - name: completed
          in: query
          description: |
            E.g. `/bundles/?completed_after=2024-10-01&completed_before=2024-10-08`
          required: false
          schema:
            type: string
            format: date-time
        - name: template
          in: query
          description: |
            Filter bundles by template ID. Only bundles created from the specified template will be returned.

            E.g. `/bundles/?template=a053644f-e371-4883-ac17-534445993346`
          required: false
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: A paged array of Bundles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundles'
    post:
      summary: Create a Bundle
      operationId: createBundle
      description: |
        Create a new Bundle (signing workflow) consisting of one or more Documents and one
        or more Signers. The Bundle is launched immediately upon creation, sending the
        documents to the signers for signature.

        ## Document sources

        Each Document in the `documents` array can be provided in one of several ways. Specify
        exactly one source per document:

        - **`file_url`** — a publicly accessible URL of a PDF file that Blueink will download.
        - **`file_b64`** — a base64-encoded PDF file embedded directly in the request.
        - **`file_html`** — an HTML string that Blueink converts to a PDF and inspects for
          form fields. See [Generate PDFs from HTML](/docs/guides/html-to-pdf/).
        - **`file_index`** — when uploading files via `multipart/form-data`, the index of the
          file in the `files` array. See the multipart request schema below.

        To create a Bundle from a pre-built Envelope Template instead, use the
        [Create a Bundle from an Envelope Template](/docs/api/create-bundle-from-envelope-template)
        endpoint.
      tags:
        - Bundles
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.bundles.create(data={
                'label': 'Mutual NDA - Acme Corp',
                'custom_key': 'deal-1042',
                'is_test': True,
                'email_subject': 'Please sign the NDA',
                'packets': [
                    {
                        'key': 'signer-1',
                        'name': 'Jordan Lee',
                        'email': 'jordan.lee@example.com',
                        'deliver_via': 'email',
                    }
                ],
                'documents': [
                    {
                        'key': 'nda',
                        'file_url': 'https://example.com/contracts/mutual-nda.pdf',
                    }
                ],
            })

            print(response.data.id)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.bundles.create({
              label: 'Mutual NDA - Acme Corp',
              custom_key: 'deal-1042',
              is_test: true,
              email_subject: 'Please sign the NDA',
              packets: [
                {
                  key: 'signer-1',
                  name: 'Jordan Lee',
                  email: 'jordan.lee@example.com',
                  deliver_via: 'email',
                },
              ],
              documents: [
                {
                  key: 'nda',
                  file_url: 'https://example.com/contracts/mutual-nda.pdf',
                },
              ],
            });

            console.log(response.data.id);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using Blueink.Client.Net.v2;
            using Blueink.Client.Net.v2.Helper;
            using Blueink.Client.Net.v2.Model;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var bundle = new BundleHelper
                {
                    Label = "Mutual NDA - Acme Corp",
                    CustomKey = "deal-1042",
                    EmailSubject = "Please sign the NDA",
                    IsTest = true,
                };

                bundle.AddSigner(
                    name: "Jordan Lee",
                    email: "jordan.lee@example.com",
                    phone: null,
                    deliveryVia: DeliveryVia.Email,
                    key: "signer-1");

                bundle.AddDocumentByUrl(
                    key: "nda",
                    url: "https://example.com/contracts/mutual-nda.pdf");

                var created = client.BundleResource
                    .CreateBundleFromHelper(bundle)
                    .Execute();

                Console.WriteLine(created.Id);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->bundles->create([
                'label' => 'Mutual NDA - Acme Corp',
                'custom_key' => 'deal-1042',
                'is_test' => true,
                'email_subject' => 'Please sign the NDA',
                'packets' => [
                    [
                        'key' => 'signer-1',
                        'name' => 'Jordan Lee',
                        'email' => 'jordan.lee@example.com',
                        'deliver_via' => 'email',
                    ],
                ],
                'documents' => [
                    [
                        'key' => 'nda',
                        'file_url' => 'https://example.com/contracts/mutual-nda.pdf',
                    ],
                ],
            ]);

            echo $response->data['id'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/bundles/ \
              --header 'Authorization: Token YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
                "label": "Mutual NDA - Acme Corp",
                "custom_key": "deal-1042",
                "is_test": true,
                "email_subject": "Please sign the NDA",
                "packets": [
                  {
                    "key": "signer-1",
                    "name": "Jordan Lee",
                    "email": "jordan.lee@example.com",
                    "deliver_via": "email"
                  }
                ],
                "documents": [
                  {
                    "key": "nda",
                    "file_url": "https://example.com/contracts/mutual-nda.pdf"
                  }
                ]
              }'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BundleRequest'
            examples:
              file_url_bundle:
                summary: Send a bundle using a hosted PDF
                value:
                  label: Mutual NDA - Acme Corp
                  custom_key: deal-1042
                  is_test: true
                  email_subject: Please sign the NDA
                  packets:
                    - key: signer-1
                      name: Jordan Lee
                      email: jordan.lee@example.com
                      deliver_via: email
                  documents:
                    - key: nda
                      file_url: https://example.com/contracts/mutual-nda.pdf
          multipart/form-data:
            schema:
              type: object
              description: |
                If your request to create a Bundle includes actual files (as opposed to URLs
                of files), you need to use a content type of multipart/form-data. The body
                of the request will then have 2 parts: a 'files' array and a 'bundle_request'
                object.

                bundle_request is a JSON object encoded as a string, with the same
                structure as the application/json content type request to this endpoint.

                files is an array of the files you are uploading as part of the request. The
                bundle_request 'documents' array will refer to these files by there array index.
              properties:
                files:
                  type: array
                  items:
                    type: string
                    format: binary
                bundle_request:
                  $ref: '#/components/schemas/BundleRequest'
      responses:
        '201':
          description: |
            Returned when the Bundle is successfully created. Note that some Bundle processing (like
            parsing tags in documents, or processing large documents) can be time consuming. Therefore
            this request return a '201' success message after preliminary data validation has been performed.
            At this point, not all documents are guaranteed to have been processed, so it is possible
            that Bundle creation could fail with a document processing error. If that is the case,
            the error status will be reflected in the Bundle response returned by a subsequent call
            to retrieve a Bundle.

            Any errors are also reported via webhooks, so your App or integration
            does not need to poll to confirm successful Bunde creation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
              examples:
                created_bundle:
                  summary: Bundle created and queued for delivery
                  value:
                    id: f9K2mQ7xLp
                    status: pe
                    created: '2026-06-24T15:04:05Z'
                    label: Mutual NDA - Acme Corp
                    custom_key: deal-1042
                    is_test: true
                    packets:
                      - id: 8ab12cde
                        key: signer-1
                        name: Jordan Lee
                        email: jordan.lee@example.com
                        status: ne
                        deliver_via: email
                        order: 1
                    documents:
                      - key: nda
                        name: Mutual_NDA.pdf
                    tags: []
        '400':
          $ref: '#/components/responses/400BadRequest'
  /bundles/create_from_envelope_template/:
    post:
      summary: Create a Bundle from an Envelope Template
      operationId: createBundleFromEnvelopeTemplate
      tags:
        - Bundles
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.bundles.create_from_envelope_template(data={
                'label': 'Employment Offer Packet',
                'is_test': True,
                'packets': [
                    {
                        'key': 'employee',
                        'name': 'Sam Rivera',
                        'email': 'sam.rivera@example.com',
                    }
                ],
                'envelope_template': {
                    'template_id': 'T-vdVRCMmtmz',
                    'field_values': [
                        {'key': 'start_date', 'initial_value': '2026-07-01'},
                        {'key': 'salary', 'initial_value': 125000},
                    ],
                },
            })

            print(response.data.id)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.bundles.createFromEnvelopeTemplate({
              label: 'Employment Offer Packet',
              is_test: true,
              packets: [
                {
                  key: 'employee',
                  name: 'Sam Rivera',
                  email: 'sam.rivera@example.com',
                },
              ],
              envelope_template: {
                template_id: 'T-vdVRCMmtmz',
                field_values: [
                  { key: 'start_date', initial_value: '2026-07-01' },
                  { key: 'salary', initial_value: 125000 },
                ],
              },
            });

            console.log(response.data.id);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using System.Collections.Generic;
            using Blueink.Client.Net.v2;
            using Blueink.Client.Net.v2.Helper;
            using Blueink.Client.Net.v2.Model;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var bundle = new BundleHelper
                {
                    Label = "Employment Offer Packet",
                    IsTest = true,
                };

                bundle.AddSigner(
                    name: "Sam Rivera",
                    email: "sam.rivera@example.com",
                    phone: null,
                    deliveryVia: DeliveryVia.Email,
                    key: "employee");

                bundle.SetEnvelopeTemplate(
                    "T-vdVRCMmtmz",
                    new Dictionary<string, string>
                    {
                        ["start_date"] = "2026-07-01",
                        ["salary"] = "125000",
                    });

                var created = client.BundleResource
                    .CreateBundleFromEnvelopeTemplate(bundle)
                    .Execute();

                Console.WriteLine(created.Id);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->bundles->createFromEnvelopeTemplate([
                'label' => 'Employment Offer Packet',
                'is_test' => true,
                'packets' => [
                    [
                        'key' => 'employee',
                        'name' => 'Sam Rivera',
                        'email' => 'sam.rivera@example.com',
                    ],
                ],
                'envelope_template' => [
                    'template_id' => 'T-vdVRCMmtmz',
                    'field_values' => [
                        ['key' => 'start_date', 'initial_value' => '2026-07-01'],
                        ['key' => 'salary', 'initial_value' => 125000],
                    ],
                ],
            ]);

            echo $response->data['id'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/bundles/create_from_envelope_template/ \
              --header 'Authorization: Token YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
                "label": "Employment Offer Packet",
                "is_test": true,
                "packets": [
                  {
                    "key": "employee",
                    "name": "Sam Rivera",
                    "email": "sam.rivera@example.com"
                  }
                ],
                "envelope_template": {
                  "template_id": "T-vdVRCMmtmz",
                  "field_values": [
                    {
                      "key": "start_date",
                      "initial_value": "2026-07-01"
                    },
                    {
                      "key": "salary",
                      "initial_value": 125000
                    }
                  ]
                }
              }'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BundleTemplateRequest'
            examples:
              envelope_template_bundle:
                summary: Create a bundle from an envelope template
                value:
                  label: Employment Offer Packet
                  is_test: true
                  packets:
                    - key: employee
                      name: Sam Rivera
                      email: sam.rivera@example.com
                  envelope_template:
                    template_id: T-vdVRCMmtmz
                    field_values:
                      - key: start_date
                        initial_value: '2026-07-01'
                      - key: salary
                        initial_value: 125000
      responses:
        '201':
          description: The created Bundle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
              examples:
                created_bundle_from_template:
                  summary: Bundle created from an envelope template
                  value:
                    id: lL7g5Hn2Ni
                    status: se
                    created: '2026-06-24T15:10:00Z'
                    label: Employment Offer Packet
                    is_test: true
                    packets:
                      - id: a6v1qN4z8T
                        key: employee
                        name: Sam Rivera
                        email: sam.rivera@example.com
                        status: ne
                        deliver_via: email
                        order: 1
                    documents:
                      - key: offer-letter
                        name: Employment_Offer.pdf
                    tags: []
        '400':
          $ref: '#/components/responses/400BadRequest'
  /bundles/preparation_session/:
    post:
      summary: Create an embedded Bundle preparation session
      operationId: createBundlePreparationSession
      description: |
        Create a short-lived, single-use URL that hosts the Blueink Bundle
        preparation experience inside an iframe in your application. The end
        user can upload PDFs, select from your Document Templates, place
        fields, configure signers, and submit the prepared Bundle — all
        without leaving your app.

        At least one document source must be enabled. Set `upload_pdf=true`
        to allow the user to upload a PDF, and/or restrict their template
        selection by passing `template_ids` or `folder_ids`. To resume work
        on an existing Draft Bundle, pass its slug as `draft_bundle`.

        The returned `url` is valid until `expires`; load it in an iframe to
        start the session.
      tags:
        - Bundles
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.bundles.create_preparation_session(data={
                'upload_pdf': True,
                'template_ids': ['7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211'],
                'allow_search_signers': True,
                'redirect_url': 'https://app.example.com/agreements/complete',
            })

            print(response.data.url)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.bundles.createPreparationSession({
              upload_pdf: true,
              template_ids: ['7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211'],
              allow_search_signers: true,
              redirect_url: 'https://app.example.com/agreements/complete',
            });

            console.log(response.data.url);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using System.Collections.Generic;
            using Blueink.Client.Net.v2;
            using Blueink.Client.Net.v2.RequestModel;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var session = client.BundleResource.CreateBundlePreparationSession(
                    new PreparationSessionRequest
                    {
                        UploadPdf = true,
                        TemplateIds = new List<string>
                        {
                            "7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211",
                        },
                        AllowSearchSigners = true,
                        RedirectUrl = "https://app.example.com/agreements/complete",
                    }).Execute();

                Console.WriteLine(session.Url);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->bundles->createPreparationSession([
                'upload_pdf' => true,
                'template_ids' => ['7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211'],
                'allow_search_signers' => true,
                'redirect_url' => 'https://app.example.com/agreements/complete',
            ]);

            echo $response->data['url'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/bundles/preparation_session/ \
              --header 'Authorization: Token YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
                "upload_pdf": true,
                "template_ids": ["7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211"],
                "allow_search_signers": true,
                "redirect_url": "https://app.example.com/agreements/complete"
              }'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BundlePreparationSessionRequest'
            examples:
              template_restricted_session:
                summary: Start a bundle preparation session with template access
                value:
                  upload_pdf: true
                  template_ids:
                    - 7b7a94a2-5f0a-4c85-a5af-2dd4e5d56211
                  allow_search_signers: true
                  redirect_url: https://app.example.com/agreements/complete
      responses:
        '201':
          description: The preparation session was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreparationSessionResponse'
              examples:
                created_preparation_session:
                  summary: Short-lived preparation session URL
                  value:
                    url: https://app.blueink.com/prepare/emb/bundle/vurl_abc123/secret_xyz
                    expires: '2026-06-24T16:10:00Z'
        '400':
          $ref: '#/components/responses/400BadRequest'
  /bundles/{bundleSlug}/:
    get:
      summary: Retrieve a Bundle
      description: >
        Retrieve a Bundle by its slug. Optionally include additional related data such as form field data,

        audit events, and downloadable files using the `include` query parameter.


        ## Using the include parameter


        The `include` parameter allows you to fetch related data in a single API call instead of making

        separate requests to the `/data`, `/events`, and `/files` endpoints. This can significantly

        reduce the number of API calls needed and improve performance.


        ### Examples:


        **Basic bundle retrieval:**

        ```

        GET /api/v2/bundles/abc123/

        ```


        **Include form data only:**

        ```

        GET /api/v2/bundles/abc123/?include=data

        ```


        **Include events and files:**

        ```

        GET /api/v2/bundles/abc123/?include=events,files

        ```


        **Include all additional data:**

        ```

        GET /api/v2/bundles/abc123/?include=data,events,files

        ```


        ### Data Availability


        - **data**: Only available for completed bundles, unless early data access is enabled for your account

        - **events**: Always available for any bundle

        - **files**: Only available for completed bundles with final documents ready, unless early file access is
        enabled


        When data or files are not available, the corresponding field will be `null` in the response.
      operationId: retrieveBundle
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
        - $ref: '#/components/parameters/include'
      responses:
        '200':
          description: A Bundle object, optionally with additional included data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BundleWithIncludes'
              examples:
                basic_bundle:
                  summary: Basic bundle without includes
                  description: Standard bundle response without any additional data
                  value:
                    id: abc123
                    status: co
                    label: Employment Contract - John Doe
                    created: '2024-01-15T10:30:00Z'
                    docs_ready: true
                    packets: []
                    documents: []
                    tags: []
                bundle_with_data:
                  summary: Bundle with form data included
                  description: Bundle response including form field data entered by signers
                  value:
                    id: abc123
                    status: co
                    label: Employment Contract - John Doe
                    created: '2024-01-15T10:30:00Z'
                    docs_ready: true
                    packets: []
                    documents: []
                    tags: []
                    data:
                      - field_name: employee_name
                        field_value: John Doe
                        field_type: text
                bundle_with_all:
                  summary: Bundle with all includes
                  description: Bundle response with data, events, and files included
                  value:
                    id: abc123
                    status: co
                    label: Employment Contract - John Doe
                    created: '2024-01-15T10:30:00Z'
                    docs_ready: true
                    packets: []
                    documents: []
                    tags: []
                    data:
                      - field_name: employee_name
                        field_value: John Doe
                        field_type: text
                    events:
                      - kind: bc
                        description: Bundle created
                        timestamp: '2024-01-15T10:30:00Z'
                      - kind: bl
                        description: Bundle launched
                        timestamp: '2024-01-15T10:35:00Z'
                    files:
                      - file_url: https://api.blueink.com/files/download/xyz789
                        expires: '2024-01-16T10:30:00Z'
        '400':
          description: Bad Request - Invalid include parameter values
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                invalid_include:
                  summary: Invalid include parameter
                  value:
                    error: 'Invalid include parameters: invalid_param. Supported: data, events, files'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Partially Update a Bundle
      description: |
        Partially update selected Bundle fields.

        Allowed fields:
        - `team`
        - `expires`
        - `cc_sender`
        - `cc_emails`
        - `send_reminders`
        - `reminder_offset`
        - `reminder_interval`
        - `reminder_expires`
        - `owner`

        Notes:
        - Only Bundles in `dr` (Draft) or `se` (Sent) status can be updated.
        - Full updates (`PUT`) are not supported. Use `PATCH`.
        - `owner` updates are restricted to account admins.
        - `team` updates require the Teams feature.
        - Reminder fields require the Reminders feature.
        - For Sent (`se`) Bundles, updating `expires` changes the date while preserving the existing time-of-day.
      operationId: updateBundlePartial
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BundlePatchRequest'
            examples:
              full_patch_example:
                summary: Update all supported fields
                value:
                  owner: 7f3c9f91-7be8-4e7f-9965-77e2f0b781d8
                  team: 22f23753-7fbe-42de-8eda-031423f965af
                  expires: '2026-03-14'
                  reminder_offset: 1
                  reminder_interval: 0
                  reminder_expires: 0
                  send_reminders: true
                  cc_emails:
                    - manager@example.com
                    - admin@example.com
                  cc_sender: false
              minimal_patch_example:
                summary: Update a single field
                value:
                  cc_sender: true
      responses:
        '200':
          description: The updated Bundle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          description: |
            Bad Request. Possible causes include:
            - invalid or disallowed fields in request body
            - Bundle status does not allow updates
            - account feature requirements not met (Teams or Reminders)
            - invalid owner/team/expires value
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          $ref: '#/components/responses/404NotFound'
  /bundles/{bundleSlug}/cancel/:
    put:
      summary: Cancel a Bundle
      operationId: cancelBundle
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: The cancelled Bundle object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Cannot cancel the bundle, probably because it is completed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /bundles/{bundleSlug}/validate/:
    put:
      summary: Validate a Bundle
      description: |
        Check if a given draft or pending Bundle is ready to be sent.
        Returns validation status and a message.
      operationId: validateBundle
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                type: object
                properties:
                  can_send:
                    type: boolean
                  msg:
                    type: string
                  n_docs:
                    type: integer
        '404':
          $ref: '#/components/responses/404NotFound'
  /bundles/{bundleSlug}/send/:
    post:
      summary: Send a Bundle
      description: |
        Attempt to send a draft or pending Bundle. If successful, the Bundle's status will change to `se` (Sent).
      operationId: sendBundle
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: The sent Bundle object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
  /bundles/{bundleSlug}/events/:
    get:
      summary: List Bundle Events
      description: Get a list of Events that are associated with the Bundle
      operationId: listBundleEvents
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: A list of events associated with this bundle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Events'
        '404':
          $ref: '#/components/responses/404NotFound'
  /bundles/{bundleSlug}/files/:
    get:
      summary: Retrieve Bundle Files
      description: Get downloadable files for a completed Bundle
      operationId: getBundleFiles
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: File response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Files'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Files not ready
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    put:
      summary: Generate Interim Bundle Files
      description: |
        Start asynchronous generation of documents in their current state. The interim documents will include
        data from any completed signing session. **Note** generating interim documents can take some time and
        happens asynchronously. You can poll the `/bundles/{bundleSlug}/` endpoint to check for a
        `doc_status` of 'in' (interim) to determine when the interim docs have completed generating. You can then
        fetch the documents using the `/bundles/{bundleSlug}/files/` endpoint. Note that the ability to generate
        interim files is not active for all API-enabled accounts. Check with Blueink support with any questions.
      operationId: generateInterimFiles
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: A Bundle object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '403':
          description: User or Account is not permitted to generate interim files
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Bundle is in terminal state. Interim files cannot be generated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /bundles/{bundleSlug}/data/:
    get:
      summary: Retrieve Bundle Data
      description: Get data entered into fields for a completed Bundle
      operationId: getBundleData
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      responses:
        '200':
          description: Data response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BundleData'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Files not ready
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /bundles/{bundleSlug}/add_tags/:
    put:
      summary: Add Tags to a bundle
      description: |
        Add additional tags to a Bundle. No existing tags on the Bundle are removed. The result
        of this call is that Bundle.tags is the union of the set of previous tags with the set of new tags.
        Duplicate tags are ignored.
      operationId: addBundleTags
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                tags:
                  $ref: '#/components/schemas/Tags'
      responses:
        '200':
          description: The modified Bundle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
  /bundles/{bundleSlug}/remove_tags/:
    put:
      summary: Remove Tags from a bundle
      description: |
        Remove tags from a Bundle. If a tag in the request does not exist on the Bundle, it is ignored.
      operationId: removeBundleTags
      tags:
        - Bundles
      parameters:
        - $ref: '#/components/parameters/bundleSlug'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                tags:
                  $ref: '#/components/schemas/Tags'
      responses:
        '200':
          description: The modified Bundle
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Bundle'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
  /packets/{packetId}/:
    get:
      summary: Retrieve a Packet
      description: |
        Retrieve details for a specific Packet (signer). This endpoint provides information about
        the signer including their contact information, signing status, authentication requirements,
        and associated Bundle information.
      operationId: retrievePacket
      tags:
        - Packet
      parameters:
        - $ref: '#/components/parameters/packetId'
      responses:
        '200':
          description: Packet details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Packet'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Update a Packet
      description: |
        Update a Packet (aka signer) with a new email, phone number, name or authentication options

        The updated packet must still be deliverable. For instance, if you specify a `deliver_via`
        value of 'phone', but there was no phone number set in the original PacketRequest, then
        this request must include a `phone` as well, or an error will be returned.

        You can change a Packet that was originally configured for embedded signing (that is, deliver_via was
        'embed') to be delivered via email or SMS. However, no signing notifications or reminders will be
        automatically sent. You must call /packet/{packetId}/remind/ to send a signing notification email (or SMS).

        If this Signer is associated with a Person, the person will be updated as well - the Person name
        will be changed (if provided) and any new email or phone number will be added.
      operationId: updatePacket
      tags:
        - Packet
      parameters:
        - $ref: '#/components/parameters/packetId'
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/PacketCommon'
                - type: object
                  properties:
                    deliver_via:
                      type: string
                      description: Note that "embed" is not an option
                      enum:
                        - email
                        - phone
      responses:
        '200':
          description: Ok, the Packet was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Packet'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
  /packets/{packetId}/embed_url/:
    post:
      summary: Create an Embedded Signing URL
      description: |
        Create a URL which can be used for embedded signing

        **Example Websites**  
        - [JavaScript Example Website](https://js-example.blueink.com)  
        - [Python Example Website](https://api-examples-python.blueink.com)  
        - [PHP Example Website](https://php-example.blueink.com)
      operationId: createPacketEmbedURL
      tags:
        - Packet
      parameters:
        - $ref: '#/components/parameters/packetId'
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.packets.embed_url(packet_id='8ab12cde')

            print(response.data.url)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.packets.embedUrl('8ab12cde');

            console.log(response.data.url);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using Blueink.Client.Net.v2;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var signing = client.PacketResource
                    .CreateEmbeddedSigningUrl("8ab12cde")
                    .Execute();

                Console.WriteLine(signing.Url);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->packets->embedURL('8ab12cde');

            echo $response->data['url'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/packets/8ab12cde/embed_url/ \
              --header 'Authorization: Token YOUR_API_KEY'
      responses:
        '201':
          description: Created response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbedURL'
              examples:
                embedded_signing_url:
                  summary: Embedded signing session URL
                  value:
                    url: https://app.blueink.com/sign/8ab12cde/example-secret
                    expires: '2026-06-24T16:20:00Z'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Cannot get an embedded url for this packet
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /packets/{packetId}/remind/:
    put:
      summary: Send a Reminder
      description: >
        Send a Reminder email or SMS to a Signer. A reminder can only be sent once every hour. The reminder will be sent
        via the delivery method (email or SMS) and to the email address (or phone number) previously designated for this
        Packet.
      operationId: sendPacketReminder
      tags:
        - Packet
      parameters:
        - $ref: '#/components/parameters/packetId'
      responses:
        '200':
          description: Ok, the reminder was sent
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Packet'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: >
            Cannot send a reminder to this packet, probably because the packet is complete (ie, the signer has already
            finished signing)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /packets/{packetId}/coe/:
    get:
      summary: Retrieve Packet Certificate of Evidence
      description: Get a link and checksum of the Certificate of Evidence for this Packet
      operationId: getPacketCOE
      tags:
        - Packet
      parameters:
        - $ref: '#/components/parameters/packetId'
      responses:
        '200':
          description: COE response
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/File'
                  - type: object
                    properties:
                      sha256:
                        type: string
                        description: the sha256 hash of the file
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: COE not available
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /templates/:
    get:
      summary: List Document Templates
      operationId: listTemplates
      tags:
        - Templates
      parameters:
        - in: query
          name: metadata[key]
          schema:
            type: string
          description: |
            Filter templates by a metadata value. Replace `key` with the metadata
            key name (e.g. `metadata[department]=legal`). Only templates whose
            stored metadata contains the matching key/value pair are returned.
            Multiple `metadata[key]` filters are ANDed together.
      responses:
        '200':
          description: A response with a list or Document Templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentTemplate'
  /templates/{templateId}/:
    get:
      summary: Retrieve a Document Template
      operationId: retrieveTemplate
      parameters:
        - $ref: '#/components/parameters/templateId'
      tags:
        - Templates
      responses:
        '200':
          description: A Document Templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentTemplate'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Update a Document Template
      operationId: updateTemplate
      description: |
        Update writable fields on a Document Template. Currently only `metadata`
        is writable via this endpoint; all other fields (name, roles, fields, etc.)
        are managed through the Blueink UI or the template preparation session.
      parameters:
        - $ref: '#/components/parameters/templateId'
      tags:
        - Templates
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                metadata:
                  type: object
                  description: |
                    Developer-controlled key/value metadata. Shallow-merged onto
                    the existing value: send key/value pairs to set or update
                    individual keys, a value of `""` to delete that key, or a
                    top-level `""` to wipe all metadata.
                  additionalProperties:
                    type: string
                    maxLength: 500
      responses:
        '200':
          description: The updated Document Template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DocumentTemplate'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
  /templates/preparation_session/:
    post:
      summary: Create an embedded Document Template preparation session
      operationId: createTemplatePreparationSession
      description: |
        Create a short-lived, single-use URL that hosts the Blueink Document
        Template authoring experience inside an iframe in your application.
        The end user can upload a PDF, define roles, place fields, and save
        the template — all without leaving your app.

        Pass `template_id` to open an existing Document Template for
        editing. Omit it to start a new-template authoring flow; `team` and
        `library` are only applied in that case (they are ignored when
        `template_id` is provided).

        The returned `url` is valid until `expires`; load it in an iframe to
        start the session.

        Requires the `API_PREPARE_DOC_TEMPLATE` account feature; the request
        returns `403` if the feature is not enabled.
      tags:
        - Templates
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.templates.create_preparation_session(data={
                'team': '22f23753-7fbe-42de-8eda-031423f965af',
                'library': 'lib_contracts',
                'redirect_url': 'https://app.example.com/templates/complete',
                'metadata': {
                    'department': 'legal',
                    'source': 'partner-portal',
                },
            })

            print(response.data.url)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.templates.createPreparationSession({
              team: '22f23753-7fbe-42de-8eda-031423f965af',
              library: 'lib_contracts',
              redirect_url: 'https://app.example.com/templates/complete',
              metadata: {
                department: 'legal',
                source: 'partner-portal',
              },
            });

            console.log(response.data.url);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using System.Collections.Generic;
            using Blueink.Client.Net.v2;
            using Blueink.Client.Net.v2.RequestModel;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var session = client.TemplateResource.CreateTemplatePreparationSession(
                    new TemplatePreparationSessionRequest
                    {
                        Team = "22f23753-7fbe-42de-8eda-031423f965af",
                        Library = "lib_contracts",
                        RedirectUrl = "https://app.example.com/templates/complete",
                        Metadata = new Dictionary<string, string>
                        {
                            ["department"] = "legal",
                            ["source"] = "partner-portal",
                        },
                    }).Execute();

                Console.WriteLine(session.Url);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->templates->createPreparationSession([
                'team' => '22f23753-7fbe-42de-8eda-031423f965af',
                'library' => 'lib_contracts',
                'redirect_url' => 'https://app.example.com/templates/complete',
                'metadata' => [
                    'department' => 'legal',
                    'source' => 'partner-portal',
                ],
            ]);

            echo $response->data['url'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/templates/preparation_session/ \
              --header 'Authorization: Token YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
                "team": "22f23753-7fbe-42de-8eda-031423f965af",
                "library": "lib_contracts",
                "redirect_url": "https://app.example.com/templates/complete",
                "metadata": {
                  "department": "legal",
                  "source": "partner-portal"
                }
              }'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplatePreparationSessionRequest'
            examples:
              new_template_session:
                summary: Start a new document template authoring session
                value:
                  team: 22f23753-7fbe-42de-8eda-031423f965af
                  library: lib_contracts
                  redirect_url: https://app.example.com/templates/complete
                  metadata:
                    department: legal
                    source: partner-portal
      responses:
        '201':
          description: The template preparation session was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreparationSessionResponse'
              examples:
                created_template_preparation_session:
                  summary: Short-lived template authoring session URL
                  value:
                    url: https://app.blueink.com/prepare/emb/template/vurl_def456/secret_xyz
                    expires: '2026-06-24T16:30:00Z'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '403':
          description: The `API_PREPARE_DOC_TEMPLATE` feature is not enabled for this account.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /persons/:
    get:
      summary: List Persons
      operationId: listPersons
      tags:
        - Person
      parameters:
        - name: search
          in: query
          description: A search query.
          required: false
          schema:
            type: string
        - name: email
          in: query
          description: |
            Filter persons by email address. Only persons with the specified email will be returned.

            E.g. `/persons/?email=john@example.com`
          required: false
          schema:
            type: string
            format: email
        - name: phone
          in: query
          description: |
            Filter persons by phone number. Only persons with the specified phone number will be returned.

            E.g. `/persons/?phone=+1234567890`
          required: false
          schema:
            type: string
      responses:
        '200':
          description: A response with a list of Persons
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Persons'
    post:
      summary: Create a Person
      operationId: createPerson
      tags:
        - Person
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Person'
      responses:
        '201':
          description: The created Person
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '400':
          $ref: '#/components/responses/400BadRequest'
  /persons/{personId}/:
    get:
      summary: Retrieve a Person
      operationId: getPerson
      parameters:
        - $ref: '#/components/parameters/personId'
      tags:
        - Person
      responses:
        '200':
          description: A response with a Person
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '404':
          $ref: '#/components/responses/404NotFound'
    put:
      summary: Update a Person
      operationId: updatePerson
      description: >
        Update the Person with new data. NOTE that any contact channels that are omitted from this request will be
        DELETED. If you don't want to replace all data on the Person, you probably want to use PATCH instead.
      parameters:
        - $ref: '#/components/parameters/personId'
      tags:
        - Person
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Person'
      responses:
        '200':
          description: The Person was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Partially update a Person
      operationId: updatePersonPartial
      description: |
        Partially update the Person with new data.

        To add a new email or phone to the Person, include a ContactChannel in the 'channels' array
        without an 'id'.

        To update an existing ContactChannel associated with the Person, include an 'id'. That existing
        ContactChannel will be updated with the new email or phone. This will update any live Bundles
        associated with the Person that are sending to that email (or phone).

        If a ContactChannel does not include an 'id', but the email (or phone) matches an existing
        ContactChannel, then that ContactChannel will not be changed.
      parameters:
        - $ref: '#/components/parameters/personId'
      tags:
        - Person
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Person'
      responses:
        '200':
          description: The Person was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    delete:
      summary: Delete a Person
      parameters:
        - $ref: '#/components/parameters/personId'
      operationId: deletePerson
      tags:
        - Person
      responses:
        '204':
          description: The Person was deleted. No content is returned
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Cannot delete the Person, probably because it is associated with live Bundles
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /webhooks/:
    get:
      summary: List Webhooks
      operationId: listWebhooks
      tags:
        - Webhook
      parameters:
        - name: enabled
          in: query
          description: |
            Only Webhooks matching the selected 'enabled' state will be returned.

            E.g. `/webhooks/?enabled=true`
          required: false
          schema:
            type: boolean
        - name: event_type
          in: query
          description: |
            Only Webhooks matching the selected event_type or event_types will be returned.

            E.g. `/webhooks/?event_type=bundle_sent`
            E.g. `/webhooks/?event_type__in=bundle_error,bundle_cancelled`
          required: false
          schema:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
              - packet_declined
      responses:
        '200':
          description: A response with a list of Webhooks
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhooks'
    post:
      summary: Create a Webhook
      operationId: createWebhook
      tags:
        - Webhook
      x-codeSamples:
        - lang: Python
          label: Python SDK
          source: |
            from blueink import Client

            client = Client('YOUR_API_KEY')

            response = client.webhooks.create(data={
                'name': 'Production signing events',
                'url': 'https://example.com/webhooks/blueink',
                'enabled': True,
                'json': True,
                'event_types': [
                    'bundle_complete',
                    'packet_complete',
                    'packet_declined',
                ],
            })

            print(response.data.id)
        - lang: JavaScript
          label: JavaScript SDK
          source: |
            import { Client } from 'blueink-client-js';

            const client = new Client('YOUR_API_KEY');

            const response = await client.webhooks.create({
              name: 'Production signing events',
              url: 'https://example.com/webhooks/blueink',
              enabled: true,
              json: true,
              event_types: ['bundle_complete', 'packet_complete', 'packet_declined'],
            });

            console.log(response.data.id);
        - lang: C#
          label: .NET SDK
          source: |
            using System;
            using System.Collections.Generic;
            using Blueink.Client.Net.v2;
            using Blueink.Client.Net.v2.Model;

            using (var client = new BlueinkService("YOUR_API_KEY"))
            {
                var webhook = client.WebhookResource.Create(
                    name: "Production signing events",
                    url: "https://example.com/webhooks/blueink",
                    enabled: true,
                    json: true,
                    eventTypes: new List<EventType>
                    {
                        EventType.BundleComplete,
                        EventType.PacketComplete,
                    },
                    extraheaders: null).Execute();

                Console.WriteLine(webhook.Id);
            }
        - lang: PHP
          label: PHP SDK
          source: |
            <?php
            use Blueink\ClientSDK\Client;

            $client = new Client('YOUR_API_KEY');

            $response = $client->webhooks->create([
                'name' => 'Production signing events',
                'url' => 'https://example.com/webhooks/blueink',
                'enabled' => true,
                'json' => true,
                'event_types' => [
                    'bundle_complete',
                    'packet_complete',
                    'packet_declined',
                ],
            ]);

            echo $response->data['id'];
        - lang: cURL
          label: cURL
          source: |
            curl --request POST \
              --url https://api.blueink.com/api/v2/webhooks/ \
              --header 'Authorization: Token YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
                "name": "Production signing events",
                "url": "https://example.com/webhooks/blueink",
                "enabled": true,
                "json": true,
                "event_types": [
                  "bundle_complete",
                  "packet_complete",
                  "packet_declined"
                ]
              }'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookRequest'
            examples:
              webhook_subscription:
                summary: Subscribe to completion and decline events
                value:
                  name: Production signing events
                  url: https://example.com/webhooks/blueink
                  enabled: true
                  json: true
                  event_types:
                    - bundle_complete
                    - packet_complete
                    - packet_declined
      responses:
        '201':
          description: The created Webhook
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
              examples:
                created_webhook:
                  summary: Webhook subscription created
                  value:
                    id: 8d4b7f63-6d03-4cd6-a1b6-31a6d6b9b8cc
                    name: Production signing events
                    url: https://example.com/webhooks/blueink
                    enabled: true
                    json: true
                    event_types:
                      - bundle_complete
                      - packet_complete
                      - packet_declined
                    extra_headers: []
        '400':
          $ref: '#/components/responses/400BadRequest'
  /webhooks/{webhookId}/:
    get:
      summary: Retrieve a Webhook
      operationId: getWebhook
      parameters:
        - $ref: '#/components/parameters/webhookId'
      tags:
        - Webhook
      responses:
        '200':
          description: A response with a Webhook
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '404':
          $ref: '#/components/responses/404NotFound'
    put:
      summary: Update a Webhook
      operationId: updateWebhook
      description: >
        Update the Webhook with new data. NOTE that any subscriptions that are omitted from this request will be
        DELETED. If you don't want to replace all data on the Webhook, you probably want to use PATCH instead.
      parameters:
        - $ref: '#/components/parameters/webhookId'
      tags:
        - Webhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Webhook'
      responses:
        '200':
          description: The Webhook was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Partially update a Webhook
      operationId: updateWebhookartial
      description: |
        Partially update the Webhook with new data.
      parameters:
        - $ref: '#/components/parameters/webhookId'
      tags:
        - Webhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Webhook'
      responses:
        '200':
          description: The Webhook was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    delete:
      summary: Delete a Webhook
      parameters:
        - $ref: '#/components/parameters/webhookId'
      operationId: deleteWebhook
      tags:
        - Webhook
      responses:
        '204':
          description: The Webhook was deleted. No content is returned
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Cannot delete the Webhook
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /webhooks/headers/:
    get:
      summary: List WebhookExtraHeaders
      operationId: listWebhookExtraHeaders
      tags:
        - WebhookExtraHeader
      parameters:
        - name: webhook
          in: query
          description: |
            Only WebhookExtraHeaders matching the selected webhook ID will be returned.

            E.g. `/webhooks/headers/?webhook=a053644f-e371-4883-ac17-534445993346`
          required: false
          schema:
            type: string
            format: uuid
        - name: event_type
          in: query
          description: |
            Only WebhookExtraHeaders with webhooks matching the selected event_type or event_types will be returned.

            E.g. `/webhooks/headers/?event_type=bundle_sent`
            E.g. `/webhooks/headers/?event_type__in=bundle_error,bundle_cancelled`
          required: false
          schema:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
              - packet_declined
      responses:
        '200':
          description: A response with a list of WebhookExtraHeaders
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookExtraHeaders'
    post:
      summary: Create a WebhookExtraHeader
      operationId: createWebhookExtraHeader
      tags:
        - WebhookExtraHeader
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookExtraHeader'
      responses:
        '201':
          description: The created WebhookExtraHeader
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookExtraHeader'
        '400':
          $ref: '#/components/responses/400BadRequest'
  /webhooks/headers/{webhookExtraHeaderId}/:
    get:
      summary: Retrieve a WebhookExtraHeader
      operationId: getWebhookExtraHeader
      parameters:
        - $ref: '#/components/parameters/webhookExtraHeaderId'
      tags:
        - Webhook
      responses:
        '200':
          description: A response with a WebhookExtraHeader
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookExtraHeader'
        '404':
          $ref: '#/components/responses/404NotFound'
    put:
      summary: Update a WebhookExtraHeader
      operationId: updateWebhookExtraHeader
      description: |
        Update the WebhookExtraHeader with new data
      parameters:
        - $ref: '#/components/parameters/webhookExtraHeaderId'
      tags:
        - WebhookExtraHeader
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookExtraHeader'
      responses:
        '200':
          description: The WebhookExtraHeader was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookExtraHeader'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    patch:
      summary: Partially update a WebhookExtraHeader
      operationId: updateWebhookExtraHeaderPartial
      description: |
        Partially update the WebhookExtraHeader with new data.
      parameters:
        - $ref: '#/components/parameters/webhookExtraHeaderId'
      tags:
        - WebhookExtraHeader
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookExtraHeader'
      responses:
        '200':
          description: The WebhookExtraHeader was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookExtraHeader'
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
    delete:
      summary: Delete a WebhookExtraHeader
      parameters:
        - $ref: '#/components/parameters/webhookExtraHeaderId'
      operationId: deleteWebhookExtraHeader
      tags:
        - WebhookExtraHeader
      responses:
        '204':
          description: The WebhookExtraHeader was deleted. No content is returned
        '400':
          $ref: '#/components/responses/400BadRequest'
        '404':
          $ref: '#/components/responses/404NotFound'
        '409':
          description: Cannot delete the WebhookExtraHeader
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /webhooks/events/:
    get:
      summary: List WebhookEvents
      operationId: listWebhookEvents
      tags:
        - WebhookEvent
      parameters:
        - name: webhook
          in: query
          description: |
            Only WebhookEvents matching the selected webhook ID will be returned.

            E.g. `/webhooks/events/?webhook=a053644f-e371-4883-ac17-534445993346`
          required: false
          schema:
            type: string
            format: uuid
        - name: event_type
          in: query
          description: |
            Only WebhookEvents with webhooks matching the selected event_type or event_types will be returned.

            E.g. `/webhooks/events/?event_type=bundle_sent`
            E.g. `/webhooks/events/?event_type__in=bundle_error,bundle_cancelled`
          required: false
          schema:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
        - name: status
          in: query
          description: |
            Only WebhookEvents matching the selected status will be returned.

            E.g. `/webhooks/events/?status=1`
            E.g. `/webhooks/events/?status__in=0,1,2`
          required: false
          schema:
            type: integer
        - name: success
          in: query
          description: |
            Only WebhookEvents matching the selected success status will be returned.

            E.g. `/webhooks/events/?success=true`
          required: false
          schema:
            type: boolean
        - name: date
          in: query
          description: |
            Only WebhookEvents occurring between a date range will be returned.
            Note: Dates are expressed as YYYY-MM-DD format.

            E.g. `/webhooks/events/?date_after=2022-10-01&date_before=2022-10-31`
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: A response with a list of WebhookEvents
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEvents'
  /webhooks/events/{webhookEventId}/:
    get:
      summary: Retrieve a WebhookEvent
      operationId: getWebhookEvent
      tags:
        - WebhookEvent
      parameters:
        - $ref: '#/components/parameters/webhookEventId'
      responses:
        '200':
          description: A WebhookEvent object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEvent'
        '404':
          $ref: '#/components/responses/404NotFound'
  /webhooks/deliveries/:
    get:
      summary: List WebhookEvents
      operationId: listWebhookDeliveries
      tags:
        - WebhookEvent
      parameters:
        - name: webhook
          in: query
          description: |
            Only WebhookDeliveries matching the selected webhook ID will be returned.

            E.g. `/webhooks/deliveries/?webhook=a053644f-e371-4883-ac17-534445993346`
          required: false
          schema:
            type: string
            format: uuid
        - name: webhook_event
          in: query
          description: |
            Only WebhookDeliveries matching the selected webhook_event ID will be returned.

            E.g. `/webhooks/deliveries/?webhook_event=a053644f-e371-4883-ac17-534445993346`
          required: false
          schema:
            type: string
            format: uuid
        - name: event_type
          in: query
          description: |
            Only WebhookDeliveries with webhooks matching the selected event_type or event_types will be returned.

            E.g. `/webhooks/deliveries/?event_type=bundle_sent`
            E.g. `/webhooks/deliveries/?event_type__in=bundle_error,bundle_cancelled`
          required: false
          schema:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
        - name: status
          in: query
          description: |
            Only WebhookDeliveries matching the selected status will be returned.

            E.g. `/webhooks/deliveries/?status=1`
            E.g. `/webhooks/deliveries/?status__in=0,1,2`
          required: false
          schema:
            type: integer
        - name: date
          in: query
          description: |
            Only WebhookDeliveries occurring between a date range will be returned.
            Note: Dates are expressed as YYYY-MM-DD format.

            E.g. `/webhooks/deliveries/?date_after=2022-10-01&date_before=2022-10-31`
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: A response with a list of WebhookEvents
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookEvents'
  /webhooks/deliveries/{webhookDeliveryId}/:
    get:
      summary: Retrieve a WebhookDelivery
      operationId: getWebhookDelivery
      tags:
        - WebhookEvent
      parameters:
        - $ref: '#/components/parameters/webhookDeliveryId'
      responses:
        '200':
          description: A WebhookDelivery object
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDelivery'
        '404':
          $ref: '#/components/responses/404NotFound'
  /webhooks/secret/:
    get:
      summary: Get Webhook Shared Secret
      operationId: getWebhookSecret
      tags:
        - WebhookSecret
      responses:
        '200':
          description: A response with the secret contained.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSecret'
        '403':
          description: User is not priviliged to view the shared secret.
        '404':
          description: Shared secret has not been generated yet.
  /webhooks/secret/regenerate/:
    post:
      summary: Regenerate Webhook Shared Secret
      operationId: regenerateWebhookSecret
      tags:
        - WebhookSecret
      responses:
        '200':
          description: A response with the new secret contained.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSecret'
        '403':
          description: User is not priviliged to regenerate the secret.
  /rate_limit/:
    get:
      summary: Check Rate Limit Status
      description: |
        Check the current rate limit status for your API key. This endpoint provides information
        about your current rate limit usage and remaining capacity.
      operationId: checkRateLimit
      tags:
        - Rate Limiting
      responses:
        '200':
          description: Rate limit status information
          content:
            application/json:
              schema:
                type: object
                properties:
                  limit:
                    type: integer
                    description: Maximum number of requests allowed per time window
                  remaining:
                    type: integer
                    description: Number of requests remaining in current time window
                  reset:
                    type: integer
                    description: Unix timestamp when the rate limit window resets
                  window:
                    type: integer
                    description: Rate limit window duration in seconds
  /envelope-templates/:
    get:
      summary: List Envelope Templates
      description: |
        Retrieve a paginated list of Envelope Templates available to your account.

        Envelope Templates are reusable document workflows that contain predefined documents,
        field layouts, signer roles, and configuration settings. They allow you to quickly
        generate new bundles with consistent formatting and behavior.

        **Filtering:**
        - Only enabled templates are returned by default
        - Templates are ordered by creation date (newest first)

        **Use Cases:**
        - Browse available templates for bundle creation
        - Integrate template selection into your application
        - Audit available document workflows
      operationId: listEnvelopeTemplates
      tags:
        - Envelope Templates
      responses:
        '200':
          description: Successfully retrieved envelope templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnvelopeTemplates'
              examples:
                envelope_templates_list:
                  summary: List of envelope templates
                  value:
                    - id: T-abc123def
                      created: '2024-01-15T10:30:00Z'
                      name: Employment Contract Template
                      description: Standard employment agreement with signature fields
                      is_shared: true
                      is_portal: false
                      allow_direct_signing: false
                      documents:
                        - key: contract
                          name: Employment_Agreement.pdf
                          order: 1
                      signers:
                        - key: employee
                          label: Employee
                          order: 1
                          auth_sms: false
                          auth_selfie: false
                          auth_id: false
                        - key: hr_manager
                          label: HR Manager
                          order: 2
                          auth_sms: true
                          auth_selfie: false
                          auth_id: false
                      smart_link_url: ''
                    - id: T-xyz789ghi
                      created: '2024-01-10T14:20:00Z'
                      name: Customer Onboarding Portal
                      description: Self-service customer registration with document upload
                      is_shared: false
                      is_portal: true
                      allow_direct_signing: true
                      documents:
                        - key: terms
                          name: Terms_of_Service.pdf
                          order: 1
                        - key: privacy
                          name: Privacy_Policy.pdf
                          order: 2
                      signers:
                        - key: customer
                          label: Customer
                          order: 1
                          auth_sms: false
                          auth_selfie: true
                          auth_id: true
                      smart_link_url: https://app.blueink.com/s/T-xyz789ghi
        '401':
          description: Authentication credentials were not provided or are invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: You do not have permission to access envelope templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /envelope-templates/{envelopeTemplateId}/:
    get:
      summary: Retrieve Envelope Template
      description: |
        Retrieve detailed information about a specific Envelope Template by its unique identifier.

        This endpoint provides complete details about an Envelope Template, including:
        - Template metadata (name, description, creation date)
        - Document structure and ordering
        - Signer roles and authentication requirements
        - Portal configuration (if applicable)

        **Use Cases:**
        - Get template details before creating a bundle
        - Display template information in your application
        - Validate template structure and requirements
        - Access smart link URL for portal templates
      operationId: retrieveEnvelopeTemplate
      tags:
        - Envelope Templates
      parameters:
        - $ref: '#/components/parameters/envelopeTemplateId'
      responses:
        '200':
          description: Successfully retrieved envelope template details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnvelopeTemplate'
              examples:
                employment_contract_template:
                  summary: Employment contract template
                  value:
                    id: T-abc123def
                    created: '2024-01-15T10:30:00Z'
                    name: Employment Contract Template
                    description: Standard employment agreement with signature fields for new hires
                    is_shared: true
                    is_portal: false
                    allow_direct_signing: false
                    documents:
                      - key: contract
                        name: Employment_Agreement.pdf
                        order: 1
                      - key: handbook
                        name: Employee_Handbook.pdf
                        order: 2
                    signers:
                      - key: employee
                        label: Employee
                        order: 1
                        auth_sms: false
                        auth_selfie: false
                        auth_id: false
                      - key: hr_manager
                        label: HR Manager
                        order: 2
                        auth_sms: true
                        auth_selfie: false
                        auth_id: false
                    smart_link_url: ''
                portal_template:
                  summary: Customer onboarding portal template
                  value:
                    id: T-xyz789ghi
                    created: '2024-01-10T14:20:00Z'
                    name: Customer Onboarding Portal
                    description: Self-service customer registration with document upload and identity verification
                    is_shared: false
                    is_portal: true
                    allow_direct_signing: true
                    documents:
                      - key: terms
                        name: Terms_of_Service.pdf
                        order: 1
                      - key: privacy
                        name: Privacy_Policy.pdf
                        order: 2
                    signers:
                      - key: customer
                        label: Customer
                        order: 1
                        auth_sms: false
                        auth_selfie: true
                        auth_id: true
                    smart_link_url: https://app.blueink.com/s/T-xyz789ghi
        '401':
          description: Authentication credentials were not provided or are invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: You do not have permission to access this envelope template
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Envelope template not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                template_not_found:
                  summary: Template not found error
                  value:
                    code: not_found
                    message: Envelope Template not found
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /verify/:
    post:
      summary: Verify a signed document
      operationId: verifyDocument
      description: |
        Public, unauthenticated endpoint for verifying that a PDF was signed
        through Blueink.

        Submit the SHA-256 hash of a PDF file. Blueink checks whether the
        hash matches any signed PDF, combined PDF, or Certificate of Execution
        (COE) produced for a completed Bundle.

        **Authentication**: none required. The endpoint is rate-limited for
        anonymous callers.

        **Use cases**

        - Let recipients self-verify a document they received.
        - Build a verification widget into your own portal.
        - Audit-trail checks by third parties without API credentials.

        **Response codes**

        - `200` — Hash matched a Blueink-produced document (`status: verified`).
        - `400` — Hash did not match any document (`status: invalid`) or the
          request was malformed (missing / invalid hash).
        - `429` — Rate limit exceeded.
      tags:
        - Verification
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyRequest'
      responses:
        '200':
          description: The document was verified successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyResponse'
        '400':
          description: |
            The hash did not match any Blueink document (`status: invalid`),
            the `hash` field was absent, or the value is not a valid
            64-character hex SHA-256 digest.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyResponse'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    BundlePayment:
      allOf:
        - type: object
          required:
            - billed_to
            - amount_due
          properties:
            billed_to:
              type: string
              description: |
                Signer key, as defined in the PacketRequest, indicating which Signer will need to pay.
              example: signer-1
            amount_due:
              type: number
              description: |
                The amount that the signer will need to pay in order to complete the bundle.
              minimum: 1
              maximum: 1000000
              example: 999
            payment_method_types:
              type: array
              description: |
                The payment method types that the signer can use to pay the amount due.
              items:
                type: string
                enum:
                  - card_payments
                  - us_bank_account_ach_payments
              example:
                - card_payments
          description: >
            You need to set up payout settings (Stripe Connect). After the signer has made the payment, the amount will
            be transferred to you via the previously set up Stripe account.
    BundleCommon:
      type: object
      properties:
        label:
          type: string
          description: A label to help you identify this Bundle
        in_order:
          type: boolean
          default: false
          description: >
            If true, Signers are required to sign in order, and a signing message (email or SMS) is sent to a Signer
            when previous signers have signed.
        email_subject:
          type: string
          maxLength: 400
          description: |
            A custom email subject that will be included in the email sent to each Signer.
        email_message:
          type: string
          description: >
            A custom message that will be included in the email sent to each Signers via email. A message set on the
            individual PacketRequest takes precedence.
        sms_message:
          type: string
          description: >
            A custom message that will be included in the SMS sent to each Signers. A message set on the individual
            PacketRequest takes precedence.
        requester_name:
          type: string
          deprecated: true
          description: >
            Deprecated. This field is ignored when creating or updating a Bundle, and is always returned as an empty
            string. The requester name defaults to the value configured for the Account (or Team).
        requester_email:
          type: string
          format: email
          maxLength: 254
          description: |
            The email address of the requester. Defaults to the value configured for the Account (or Team).
        cc_emails:
          type: array
          description: An array of email addresses that should be cc'd when the documents are complete
          items:
            type: string
            format: email
            maxLength: 254
        custom_key:
          type: string
          description: |
            An optional, unique custom key you can use to identify and retrieve this Bundle (e.g via search)
          maxLength: 200
        team:
          type: string
          format: uuid
          description: |
            A team ID, if teams are activated for your Account and you want to assign this Bundle to a particular team.
        is_test:
          type: boolean
          description: >
            Set to True if this a test bundle. Test Bundles do not count against any account usage limits and cannot be
            used to create legally binding eSignatures. This should always be set to true while you App or integration
            is under development.
        status:
          type: string
          enum:
            - ''
            - dr
          description: |
            Leave blank to send a bundle normally. Set to "dr" to create a draft bundle that is not sent automatically
        payment:
          $ref: '#/components/schemas/BundlePayment'
          type: object
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: |
            A code that identifies the kind of the error. One of:

            - authentication_failed: Incorrect authentication credentials provided.
            - conflict: Server is in a conflicted state and cannot handle the request.
            - error: A general error occured that cannot be described by one of the more specific error
            codes.
            - invalid: Validation of the incoming data failed. The request contained invalid input.
            - method_not_allowed: The requested method is not allowed on the API URL.
            - not_acceptable: Cannot satisfy the Accept header in the request.
            - not_authenticated: Authentication credentials were not provided.
            - not_found: The requested resource could not be found.
            - permission_denied: You do not have permission to perform the requested action.
            - parse_error: The request payload could not be parsed.
            - service_unavailable: The request failed because some part of the Blueink service is
            temporarily unavailable.
            - throttled: The request was throttled
            - unsupported_media_type: The request contained an unsupported media type.
          enum:
            - authentication_failed
            - conflict
            - error
            - invalid
            - method_not_allowed
            - not_acceptable
            - not_authenticated
            - not_found
            - permission_denied
            - parse_error
            - service_unavailable
            - throttled
            - unsupported_media_type
        message:
          type: string
          description: A human readable string describing the error
        errors:
          type: array
          description: An optional array of field-specific errors providing additional details
          required:
            - field
            - message
          items:
            type: object
            properties:
              field:
                type: string
                description: |
                  The field in the request associated with the error. For nested data, the
                  field might be specified using dot and array notation. For instance, for a
                  BundleRequest, the field value might be `documents[0].key` to indicate the error
                  is associated with the "key" field of the first document passed in the
                  documents array.

                  In some cases, the field value might not identify every component in the path
                  to the actual value in error. For example a field value of 'documents.fields'
                  indicates that one of the documents has an issue with its 'fields' value, but
                  does not identify the specific document. The message should provide
                  additional details.
              messsage:
                type: string
                description: A human readable string describing the error for this field
    PacketCommon:
      type: object
      properties:
        name:
          type: string
          description: The name of the signer
        email:
          type: string
          format: email
          maxLength: 254
          description: The email address of the signer
        phone:
          type: string
          format: phone
          maxLength: 128
          description: The phone number of the signer. Required if SMS Pin authentication is used.
        auth_sms:
          type: boolean
          description: >
            True if you would like to require SMS pin authentication before a signer can sign the documents in this
            Bundle
        auth_selfie:
          type: boolean
          description: >
            True if you would like to require Selfie authentication before a signer can sign the documents in this
            Bundle
        auth_id:
          type: boolean
          description: |
            True if you would like to require ID authentication before a signer can sign the documents in this Bundle
        signing_complete_redirect:
          type: string
          format: uri
          description: >
            URL to redirect the signer to after they complete signing. This URL takes precedence over any signing brand
            or account-level redirect settings. Requires the Signing Brands feature to be enabled on your account.
          maxLength: 400
        suppress_all:
          type: boolean
          description: >
            If true, suppresses all email and SMS notifications for this signer. This includes signing notifications,
            reminders, and completion notifications.
        suppress_docs_ready:
          type: boolean
          description: >
            If true, suppresses the "documents ready" notification email that is normally sent when all signers have
            completed the bundle.
        suppress_signing:
          type: boolean
          description: >
            If true, suppresses the initial signing notification email/SMS that is sent when the bundle is first sent to
            signers.
        suppress_reminder:
          type: boolean
          description: >
            If true, suppresses reminder emails/SMS that would normally be sent to this signer if they haven't completed
            signing within the reminder interval.
    Packet:
      allOf:
        - $ref: '#/components/schemas/PacketCommon'
        - type: object
          properties:
            id:
              type: string
            person_id:
              type: string
              format: uuid
            status:
              type: string
              enum:
                - ne
                - re
                - se
                - st
                - co
                - ca
                - ex
                - fa
            deliver_via:
              type: string
              enum:
                - email
                - phone
                - embed
            completed_at:
              type: string
            last_accessed_at:
              type: string
            order:
              type: integer
            requires_witness:
              type: boolean
              readOnly: true
              description: |
                True if this Signer requires a witness to be present and to
                co-sign. Read-only on this Packet; the witness signing flow
                is represented as a child Packet on the same Bundle.
            witness_nominated_by:
              type: string
              readOnly: true
              enum:
                - sgn
                - snd
                - ''
              description: |
                Indicates who nominates the witness for this Signer.
                Empty string if `requires_witness` is false.

                - `sgn` — Signer nominates the witness at signing time.
                - `snd` — Sender nominates the witness up front.
    BundleDocument:
      type: object
      properties:
        template_id:
          type: string
          format: uuid
          description: |
            The ID of the DocumentTemplate if this BundleDocument was created from a DocumentTemplate, null otherwise
        key:
          type: string
          description: >
            The name of the document. Defaults to the filename or the document when it was uploaded, but can be set to a
            human-friendly name.
        name:
          type: string
          description: >
            The generated filename for the this document. If the document was DocumentTemplate, this is the name of the
            DocumentTemplate. If it was generated from a file_url, this is the name extracted from the file_url (if
            possible). If it was generated from an uploaded file, this is an automatically generated name
    Tags:
      type: array
      description: An array of tags
      items:
        type: string
        description: The tag, as a string. A tag cannot contain a space or comma.
    Bundle:
      allOf:
        - $ref: '#/components/schemas/BundleCommon'
        - type: object
          properties:
            id:
              type: string
            status:
              type: string
              enum:
                - ne
                - dr
                - pr
                - pe
                - se
                - st
                - de
                - ca
                - ex
                - fa
                - co
            doc_status:
              type: string
              enum:
                - 'no'
                - di
                - pe
                - in
                - fi
              description: |
                Status of document generation for the Bundle.
                * no: None - no documents have been generated
                * pe: Pending - documents are in the process of being generated
                * di: Dirty - documents have been generated but are out of date
                * in: Interim - an interim version of the documents has been generated
                * fi: Final - final, signed versions of the documents have been generated
            created:
              type: string
              format: date-time
            docs_ready:
              type: boolean
              description: True when final documents have been generated on a complete Bundle
            errors:
              type: array
              description: An array of Errors, if any occured during document processing. Null otherwise.
              items:
                $ref: '#/components/schemas/Error'
            packets:
              type: array
              items:
                $ref: '#/components/schemas/Packet'
            documents:
              type: array
              items:
                $ref: '#/components/schemas/BundleDocument'
            tags:
              $ref: '#/components/schemas/Tags'
    Bundles:
      type: array
      items:
        $ref: '#/components/schemas/Bundle'
    PacketRequest:
      allOf:
        - $ref: '#/components/schemas/PacketCommon'
        - type: object
          required:
            - key
          properties:
            key:
              type: string
              description: >
                A string that is unique to this Bundle which is used to identify the signer elsewhere in this request.
                This key is used when mapping a signer to a role in the 'assignments' field of a TemplateRequest and is
                used to assign a field to a signer in 'editors' field in a DocumentRequestField.
              pattern: ^[-\w]+$
              minLength: 2
              maxLength: 20
            person_id:
              type: string
              format: uuid
              description: |
                The ID of an existing Person, used to locate the Person object corresponding to this
                Signer. When person_id is provided, Blueink does not use the default Person Matching
                Algorithm, and instead matches a Person based on the ID. If no Person is found, an
                error is raised.

                When a matching Person is found, that Person object will be updated with any new or
                changed data provided in this PacketRequest. If PacketRequest.name does not equal
                Person.name, Person.name will be updated. If the email or phone included in the
                PacketRequest are unknown, they will be added to the Person object.
            deliver_via:
              type: string
              enum:
                - email
                - phone
                - embed
              default: email
              description: |
                How the signing link should be delivered to this Signer. If "email" (or "phone"), then an
                email address (or phone number, respectively) must be provided in the PacketRequest, or
                sync_person must be true and a default email (or phone number, respectively)
                is set on the Person.

                If "embed", then this Signer will be configured for embedded signing. No email or SMS
                message will be sent to the Signer. In a subsequent API request, you can use the
                unique Packet ID to for this signer to retrieve an URL you can use for embedded signing.
            order:
              type: integer
    FieldFormatDateInput:
      type: string
      description: |
        Allowed `format` values for date-oriented fields of kind `dat`.
      enum:
        - ''
        - M/D/YY
        - MM/DD/YY
        - MM/DD/YYYY
        - YYYY-MM-DD
        - D/M/YY
        - D/M/YYYY
        - DD/MM/YYYY
        - MMM D, YYYY
        - MMMM D, YYYY
        - MMMM Do, YYYY
        - D MMM YYYY
        - D MMMM YYYY
    FieldFormatSigningTimestampInput:
      type: string
      description: |
        Allowed `format` values for signing timestamp fields of kind `tms`.
        This includes all date-only formats plus date-time formats with timezone.
      enum:
        - ''
        - M/D/YY
        - MM/DD/YY
        - MM/DD/YYYY
        - YYYY-MM-DD
        - D/M/YY
        - D/M/YYYY
        - DD/MM/YYYY
        - MMM D, YYYY
        - MMMM D, YYYY
        - MMMM Do, YYYY
        - D MMM YYYY
        - D MMMM YYYY
        - M/D/YY, h:mm a ZZZ
        - MM/DD/YYYY, HH:mm ZZZ
        - D/M/YY, h:mm a ZZZ
        - DD/MM/YYYY, HH:mm ZZZ
        - MMM D, YYYY, h:mm a ZZZ
        - D MMM YYYY, h:mm a ZZZ
        - D MMM YYYY, HH:mm ZZZ
        - YYYY-MM-DD HH:mm:ss ZZZ
    DocumentField:
      type: object
      required:
        - kind
        - x
        - 'y'
        - w
        - h
      properties:
        kind:
          type: string
          description: |
            The kind of field. Each field type serves a specific purpose:

            - `att` - **Attachment**: Allows signers to upload files (documents, images, etc.)
            - `cbg` - **Checkbox Group**: A group of related checkboxes where multiple options can be selected
            - `chk` - **Checkbox**: A single checkbox that can be checked or unchecked
            - `dat` - **Date**: A date picker field for entering dates
            - `ini` - **Initials**: A field for capturing the signer's initials
            - `inp` - **Text**: A single-line text input field for short text entries
            - `sel` - **Dropdown**: A dropdown/select field with predefined options
            - `sig` - **Signature**: A field for capturing the signer's electronic signature
            - `snm` - **Signer Name**: Automatically populated with the signer's name
            - `tms` - **Signing Date**: Automatically populated with the full timestamp when the document was signed
            - `txt` - **Multiline Text**: A multi-line text area for longer text entries
          enum:
            - att
            - cbg
            - chk
            - dat
            - ini
            - inp
            - sel
            - sig
            - snm
            - tms
            - txt
        label:
          type: string
          description: A label for the field which will be shown to the Signer(s)
        required:
          type: boolean
          default: false
          description: >
            If true, the final editor submitting the document cannot leave the field blank. For example, if `editors` is
            set to ['-assistant', '-manager'], the final editor must still enter a value if `required` is true
        page:
          type: integer
          description: >
            The page number on which to place this field. For attachment fields, page number is ignored and attachments
            are gathered in a separate step of the review process.
        x:
          type: number
          description: The x coordinate of the lower left corner of the field
        'y':
          type: number
          description: The y coordinate of the lower left corner of the field
        w:
          type: number
          description: The width of the field
        h:
          type: number
          description: The height of the field
        related_to_key:
          type: string
          maxLength: 12
          description: >
            For checkboxes, the key of the parent Checkbox Group field (`cbg`) that this checkbox belongs to. When
            grouped, the validation rules (like `v_min` and `v_max`) set on the parent group field are applied to the
            set of related checkboxes.
        v_pattern:
          type: string
          description: A known, common pattern to validate a value against
          enum:
            - email
            - bank_routing
            - bank_account
            - letters
            - numbers
            - phone
            - ssn
            - zip_code
        v_regex:
          type: string
          description: >
            A regular expression (RE2 syntax) that any submitted value will be evaluated against. Cannot be combined
            with v_pattern. When set, v_min and v_max are ignored. Requires the FIELD_REGEX_VALIDATION feature to be
            enabled for the account.
          maxLength: 200
        v_regex_msg:
          type: string
          description: >
            The validation error message shown to a Signer when the submitted value does not match the v_regex pattern.
            Required when v_regex is set.
          maxLength: 200
        v_min:
          type: number
          description: >
            For string fields, the minimum number of characters allowed. For number fields the minimum allowed value.
            For attachment fields, the minimum required file size in KB. For Checkbox Group fields (`cbg`), the minimum
            number of checkboxes that must be selected.
        v_max:
          type: number
          description: >
            For string fields, the maximum number of characters allowed. For number fields the maximum allowed value.
            For attachment fields, the minimum required file size in KB. For Checkbox Group fields (`cbg`), the maximum
            number of checkboxes that can be selected.
        v_attachment_types:
          type: array
          items:
            type: string
            enum:
              - jpg
              - jpeg
              - png
              - gif
              - svg
              - pdf
              - doc
              - docx
              - ppt
              - pptx
              - xls
              - xlsx
              - rtf
              - txt
        format:
          description: |
            Optional display format string for date-oriented fields.

            Supported kinds and accepted values:
            - `dat` (Date): use values from `FieldFormatDateInput`
            - `tms` (Signing Timestamp): use values from `FieldFormatSigningTimestampInput`

            For all other field kinds, `format` is not supported and will return a validation error.
          oneOf:
            - $ref: '#/components/schemas/FieldFormatDateInput'
            - $ref: '#/components/schemas/FieldFormatSigningTimestampInput'
    DocumentRequestField:
      allOf:
        - $ref: '#/components/schemas/DocumentField'
        - type: object
          properties:
            initial_value:
              description: >
                An initial value for the field. If editors is empty, then this field effectively becomes a read-only
                field that cannot be edited by any Signers. Note, validation (v_regex, v_min, v_max) is not applied to
                this value.

                Attachment type fields do not support initial_value.

                For date fields, the date must be provided as a string in the format YYYY-MM-DD, like "2019-09-20".
              oneOf:
                - type: string
                - type: boolean
                - type: number
            editors:
              type: array
              default: []
              description: |
                An array of Signer keys, as defined in the PacketRequest, indicating which Signers can
                edit this field. By default the field will be required for any Signer listed,
                meaning that when that Signer is reviewing / signing the document, they cannot leave the
                field blank.

                Note oftentimes you will not want a Checkbox field to be required - because a
                required checkbox must be checked in order for a Signer to advance past the field.

                If the field should be editable, but optional for a Signer, prefix the key with a '-'.

                For example: ['signer-1', '-signer-2'] indicates that the field is required for signer-1
                but optional for signer-2.
              items:
                type: string
    AutoPlacement:
      type: object
      required:
        - kind
        - search
      properties:
        kind:
          type: string
          description: |
            The kind of field. Each field type serves a specific purpose:

            - `att` - **Attachment**: Allows signers to upload files (documents, images, etc.)
            - `chk` - **Checkbox**: A single checkbox that can be checked or unchecked
            - `dat` - **Date**: A date picker field for entering dates
            - `ini` - **Initials**: A field for capturing the signer's initials
            - `inp` - **Text**: A single-line text input field for short text entries
            - `sel` - **Dropdown**: A dropdown/select field with predefined options
            - `sig` - **Signature**: A field for capturing the signer's electronic signature
            - `tms` - **Signing Date**: Automatically populated with the full timestamp when the document was signed
            - `txt` - **Multiline Text**: A multi-line text area for longer text entries
          enum:
            - att
            - chk
            - dat
            - ini
            - inp
            - sel
            - sig
            - tms
            - txt
        label:
          type: string
          description: A label for the field which will be shown to the Signer(s)
        search:
          type: string
          minLength: 1
          maxLength: 255
          description: |
            The text string to search for in the PDF document. The search is **case-insensitive**.

            **Allowed Characters:**
            - Letters (a-z, A-Z)
            - Numbers (0-9)
            - Spaces
            - Common punctuation and delimiters: `:`  `{{` `}}` `[` `]` `{` `}` 

            **String Length:**
            - Minimum: 1 character
            - Maximum: 255 characters

            **Case Sensitivity:**
            - Search is case-insensitive (e.g., "Signature" will match "signature", "SIGNATURE", or "SiGnAtUrE")

            **Common Pattern Examples:**
            ```
            "Signature"
            "Signature:"
            "[Signature]"
            "{Signature}"
            "{{Signature 1}}"
            "{{Signature 2}}"
            "Tenant Signature"
            "Sign Here"
            ```

            **Best Practices:**
            - Use unique, descriptive patterns to avoid unintended matches
            - Include delimiters (brackets, colons, etc.) to make patterns more specific
            - Use numbered patterns (e.g., "{{Signature 1}}", "{{Signature 2}}") to distinguish multiple similar fields
            - Test patterns with your actual PDF documents to ensure correct placement
        required:
          type: boolean
          default: false
          description: >
            If true, the final editor submitting the document cannot leave the field blank. For example, if `editors` is
            set to ['-assistant', '-manager'], the final editor must still enter a value if `required` is true
        w:
          type: number
          description: The width of the field
        h:
          type: number
          description: The height of the field
        offset_x:
          type: number
          description: The positive or negative offset in the x direction the field should be placed relative to the string found
        offset_y:
          type: number
          description: The positive or negative offset in the x direction the field should be placed relative to the string found
    AutoPlacementRequestField:
      allOf:
        - $ref: '#/components/schemas/AutoPlacement'
        - type: object
          required:
            - kind
            - search
            - editors
          properties:
            kind:
              type: string
              description: |
                The kind of field. Each field type serves a specific purpose:

                - `apr` - **Approve / Decline**: A field that allows signers to approve or decline the document
                - `att` - **Attachment**: Allows signers to upload files (documents, images, etc.)
                - `chk` - **Checkbox**: A single checkbox that can be checked or unchecked
                - `cbg` - **Checkbox Group**: A group of related checkboxes where multiple options can be selected
                - `con` - **Confirmation**: A confirmation field that requires explicit acknowledgment
                - `dat` - **Date**: A date picker field for entering dates
                - `sig` - **Signature**: A field for capturing the signer's electronic signature
                - `flt` - **Float**: A numeric field that accepts decimal numbers
                - `ini` - **Initials**: A field for capturing the signer's initials
                - `inp` - **Text**: A single-line text input field for short text entries
                - `int` - **Integer**: A numeric field that accepts whole numbers only
                - `txt` - **Multiline Text**: A multi-line text area for longer text entries
                - `sel` - **Dropdown**: A dropdown/select field with predefined options
                - `tms` - **Signing Date**: Automatically populated with the full timestamp when the document was signed
              enum:
                - apr
                - att
                - chk
                - cbg
                - con
                - dat
                - sig
                - flt
                - ini
                - inp
                - int
                - txt
                - sel
                - tms
            search:
              type: string
              minLength: 1
              maxLength: 255
              description: >
                The text string to search for in the PDF document. The search is **case-insensitive**.


                **Allowed Characters:**

                - Letters (a-z, A-Z)

                - Numbers (0-9)

                - Spaces

                - Common punctuation and delimiters: `:`  `{{` `}}` `[` `]` `{` `}` 


                **String Length:**

                - Minimum: 1 character

                - Maximum: 255 characters


                **Case Sensitivity:**

                - Search is case-insensitive (e.g., "Signature" will match "signature", "SIGNATURE", or "SiGnAtUrE")


                **Common Pattern Examples:**

                ```

                "Signature"

                "Signature:"

                "[Signature]"

                "{Signature}"

                "{{Signature 1}}"

                "{{Signature 2}}"

                "Tenant Signature"

                "Sign Here"

                ```


                **Best Practices:**

                - Use unique, descriptive patterns to avoid unintended matches

                - Include delimiters (brackets, colons, etc.) to make patterns more specific

                - Use numbered patterns (e.g., "{{Signature 1}}", "{{Signature 2}}") to distinguish multiple similar
                fields

                - Test patterns with your actual PDF documents to ensure correct placement
            w:
              type: number
            h:
              type: number
            offset_x:
              type: number
              description: Horizontal offset from found point
            offset_y:
              type: number
              description: Vertical offset from found point
            v_pattern:
              type: string
              description: A known, common pattern to validate a value against
              enum:
                - email
                - bank_routing
                - bank_account
                - letters
                - numbers
                - phone
                - ssn
                - zip_code
            v_regex:
              type: string
              description: >
                A regular expression (RE2 syntax) that any submitted value will be evaluated against. Cannot be combined
                with v_pattern. When set, v_min and v_max are ignored. Requires the FIELD_REGEX_VALIDATION feature to be
                enabled for the account.
              maxLength: 200
            v_regex_msg:
              type: string
              description: >
                The validation error message shown to a Signer when the submitted value does not match the v_regex
                pattern. Required when v_regex is set.
              maxLength: 200
            v_min:
              type: number
              description: >
                For string fields, the minimum number of characters allowed. For number fields the minimum allowed
                value. For attachment fields, the minimum required file size in KB.
            v_max:
              type: number
              description: >
                For string fields, the maximum number of characters allowed. For number fields the maximum allowed
                value. For attachment fields, the maximum allowed file size in KB.
            v_attachment_types:
              type: array
              description: >
                An array of allowed file extensions for attachment fields (kind `att`). Only valid for fields of kind
                `att`. Extensions should be provided without a leading dot (e.g. `"pdf"`, `"png"`).
              items:
                type: string
                enum:
                  - jpg
                  - jpeg
                  - png
                  - gif
                  - svg
                  - pdf
                  - doc
                  - docx
                  - ppt
                  - pptx
                  - xls
                  - xlsx
                  - rtf
                  - txt
            format:
              description: |
                Optional display format string for date-oriented fields.

                Supported kinds and accepted values:
                - `dat` (Date): use values from `FieldFormatDateInput`
                - `tms` (Signing Timestamp): use values from `FieldFormatSigningTimestampInput`

                For all other field kinds, `format` is not supported and will return a validation error.
              oneOf:
                - $ref: '#/components/schemas/FieldFormatDateInput'
                - $ref: '#/components/schemas/FieldFormatSigningTimestampInput'
            initial_value:
              description: >
                An initial value for the field. If editors is empty, then this field effectively becomes a read-only
                field that cannot be edited by any Signers. Note, validation (v_pattern, v_min, v_max) is not applied to
                this value.

                Attachment type fields do not support initial_value.

                For date fields, the date must be provided as a string in the format YYYY-MM-DD, like "2019-09-20".
              oneOf:
                - type: string
                - type: boolean
                - type: number
            editors:
              type: array
              default: []
              description: |
                An array of Signer keys, as defined in the PacketRequest, indicating which Signers can
                edit this field. By default the field will be required for any Signer listed,
                meaning that when that Signer is reviewing / signing the document, they cannot leave the
                field blank.

                Note oftentimes you will not want a Checkbox field to be required - because a
                required checkbox must be checked in order for a Signer to advance past the field.

                If the field should be editable, but optional for a Signer, prefix the key with a '-'.

                For example: ['signer-1', '-signer-2'] indicates that the field is required for signer-1
                but optional for signer-2.
              items:
                type: string
    DocumentRequest:
      type: object
      description: Only one of file_url, file_index, file_b64, or file_html can be provided.
      oneOf:
        - required:
            - file_url
        - required:
            - file_index
        - required:
            - file_b64
        - required:
            - file_html
      properties:
        key:
          type: string
          description: A string that uniquely identifies this Document in the Bundle
          pattern: ^[-\w]+$
          minLength: 2
          maxLength: 12
        file_url:
          type: string
          description: |
            The URL of a file
        file_b64:
          type: string
          description: |
            The base64 representation of a file
        file_html:
          type: string
          description: |
            An HTML string to be converted to a PDF document. Blueink renders the HTML
            to a PDF and detects signature, initial, date, and form fields based on
            standard HTML form elements and `data-blu-*` annotations on the source
            elements.

            See the [Generate PDFs from HTML](/docs/guides/html-to-pdf/)
            guide for the full HTML specification, including supported elements,
            field-detection rules, and layout requirements.
        file_index:
          type: integer
          description: |
            The index of a file uploaded separately in the `files` array (when
            the request body encoding is `multipart/form-data`).

            **Supported file formats**

            - PDF (`.pdf`).
            - MS Office documents (`.doc`, `.docx`, `.ppt`, `.pptx`, `.xls`, `.xlsx`).
              Blueink converts Office files to PDF server‑side before fields are
              placed and the Bundle is sent. Requires the `MS_OFFICE_UPLOAD`
              account feature; the request fails if the feature is not enabled.
        filename:
          type: string
          description: |
            The filename to use for the document
          maxLength: 50
        fields:
          type: array
          description: An array of fields to place on the document
          items:
            $ref: '#/components/schemas/DocumentRequestField'
        auto_placements:
          type: array
          description: An array of directions of where to place fields automatically
          items:
            $ref: '#/components/schemas/AutoPlacementRequestField'
        converted_adobe_fields_to:
          type: string
          description: >
            Signer key, as defined in the PacketRequest. If the document is an Adobe PDF,  this field can be used to
            convert any interactive fields in the document  to be assigned to the signer identified by the given key.
        html_fields_mode:
          type: string
          enum:
            - blueink
            - none
          default: blueink
          description: |
            Controls how fields are extracted when using HTML-to-PDF conversion (`file_html`).

            - `blueink` (default) — Detect form elements and `data-blu-*` annotations
              and convert them to Blueink fields.
            - `none` — Skip field detection. The HTML is rendered to a PDF and attached
              to the document, but no fields are created.

            See [Generate PDFs from HTML](/docs/guides/html-to-pdf/)
            for details.
    TemplateRequest:
      type: object
      required:
        - template_id
        - assignments
      properties:
        key:
          type: string
          description: A string that uniquely identifies this Template in the Bundle
          pattern: ^[-\w]+$
          minLength: 2
          maxLength: 12
        template_id:
          type: string
          format: uuid
          description: The ID of the Document Template
        assignments:
          type: array
          description: An array of mappings between Document Template roles and Signers
          items:
            type: object
            required:
              - role
              - signer
            properties:
              role:
                type: string
                description: The unique key identifying the unique role in this Document Template
                pattern: ^[-\w]+$
                minLength: 2
                maxLength: 12
              signer:
                type: string
                description: The signer key, as defined in the PacketRequest
        field_values:
          type: array
          description: An array of initial values to apply to fields in the document
          items:
            type: object
            required:
              - key
              - value
            properties:
              key:
                type: string
                description: The unique key identifying the field in this Document Template
                pattern: ^[-\w]+$
                minLength: 2
                maxLength: 12
              initial_value:
                description: >
                  An initial value for the field. If the field in the template allows signers to edit the field, then
                  they can edit this initial value. If no signers are assigned to the field, then this is effectively a
                  read-only value.

                  Attachment type fields do not support initial_value.

                  For date fields, the date must be provided as a string in the format YYYY-MM-DD, like "2019-09-20".
                oneOf:
                  - type: string
                  - type: boolean
                  - type: number
    BundleRequest:
      allOf:
        - $ref: '#/components/schemas/BundleCommon'
        - type: object
          required:
            - packets
            - documents
          properties:
            packets:
              type: array
              items:
                $ref: '#/components/schemas/PacketRequest'
            documents:
              type: array
              items:
                oneOf:
                  - $ref: '#/components/schemas/DocumentRequest'
                  - $ref: '#/components/schemas/TemplateRequest'
            cc_sender:
              type: boolean
              description: If true, CC the sender on completion notifications.
            send_reminders:
              type: boolean
              description: |
                Enable or disable signer reminder notifications.
                Requires the Reminders feature to be enabled.
            reminder_offset:
              type: integer
              minimum: 0
              maximum: 30
              description: |
                Number of days after send before the first reminder.
                Requires the Reminders feature to be enabled.
            reminder_interval:
              type: integer
              minimum: 0
              maximum: 30
              description: |
                Number of days between reminders.
                Requires the Reminders feature to be enabled.
            reminder_expires:
              type: integer
              minimum: 0
              maximum: 30
              description: |
                Number of days after send when reminders stop.
                Requires the Reminders feature to be enabled.
            tag_values:
              type: object
              additionalProperties: {}
              description: |
                A map of Data Flow Tag names to pre-fill values. When provided,
                any field in the Bundle whose `data_flow_tag` matches a key in
                this map will be pre-populated with the corresponding value.
                Keys must be non-empty strings; values may be strings, numbers,
                or booleans depending on the target field type.
              example:
                customer_name: Acme Corp
                contract_date: '2026-06-11'
    BundleTemplateRequest:
      allOf:
        - $ref: '#/components/schemas/BundleCommon'
        - type: object
          required:
            - envelope_template
            - packets
          properties:
            envelope_template:
              type: object
              required:
                - template_id
              properties:
                template_id:
                  type: string
                  description: >
                    The ID of the Envelope Template to use for this Bundle. It should be in the format of
                    "T-xxxxxxxxxxx", e.g., "T-vdVRCMmtmz".
                field_values:
                  type: array
                  description: An array of initial values to apply to fields in the document
                  items:
                    type: object
                    required:
                      - key
                      - initial_value
                    properties:
                      key:
                        type: string
                        description: The unique key identifying the field in this Envelope Template
                      initial_value:
                        description: >
                          An initial value for the field. If the field in the template allows signers to edit the field,
                          then they can edit this initial value. If no signers are assigned to the field, then this is
                          effectively a read-only value.

                          Attachment type fields do not support initial_value.

                          For date fields, the date must be provided as a string in the format YYYY-MM-DD, like
                          "2019-09-20".
                        oneOf:
                          - type: string
                          - type: boolean
                          - type: number
            packets:
              type: array
              items:
                type: object
                required:
                  - name
                  - email
                  - key
                properties:
                  name:
                    type: string
                    description: The name of the signer
                  email:
                    type: string
                    format: email
                    maxLength: 254
                    description: The email address of the signer
                  phone:
                    type: string
                    format: phone
                    maxLength: 128
                    description: The phone number of the signer. Required if SMS Pin authentication is used.
                  key:
                    type: string
                    description: A string that uniquely identifies this Signer in the Envelope Template
                  deliver_via:
                    type: string
                    enum:
                      - email
                      - phone
                      - embed
                    description: |
                      How the signing link should be delivered to this Signer. If "email" (or "phone"), then an
                      email address (or phone number, respectively) must be provided in the PacketRequest, or
                      sync_person must be true and a default email (or phone number, respectively)
                      is set on the Person.

                      If "embed", then this Signer will be configured for embedded signing. No email or SMS
                      message will be sent to the Signer. In a subsequent API request, you can use the
                      unique Packet ID for this signer to retrieve an URL you can use for embedded signing.
    BundlePreparationSessionRequest:
      type: object
      description: |
        Request body for `POST /bundles/preparation_session/`. At least one
        document source must be enabled — either set `upload_pdf=true`, or
        supply `template_ids`, `folder_ids`, or `draft_bundle`.
      properties:
        draft_bundle:
          type: string
          nullable: true
          description: |
            Slug of an existing Draft Bundle to open in the preparation
            session. When provided, the session resumes editing that Bundle
            rather than creating a new one.
        folder_ids:
          type: array
          nullable: true
          description: |
            Restrict template selection in the prepare UI to templates in
            these folders (template Library BUIDs).
          items:
            type: string
        template_ids:
          type: array
          nullable: true
          description: |
            Restrict template selection in the prepare UI to this explicit
            list of Document Template UUIDs.
          items:
            type: string
            format: uuid
        upload_pdf:
          type: boolean
          default: true
          description: |
            If true, the prepare UI lets the end user upload a new PDF as a
            document source. Set to false to restrict the session to the
            supplied templates / folders / draft.
        allow_search_signers:
          type: boolean
          default: false
          description: |
            If true, the prepare UI lets the end user search the account's
            Persons list when adding signers.
        redirect_url:
          type: string
          format: uri
          maxLength: 400
          nullable: true
          description: |
            Optional URL the iframe will redirect to once the preparation
            session is complete.
    PreparationSessionResponse:
      type: object
      required:
        - url
        - expires
      properties:
        url:
          type: string
          format: uri
          description: |
            Short-lived, single-use URL that hosts the embedded preparation
            experience. Load this URL in an iframe.
        expires:
          type: string
          format: date-time
          description: |
            ISO‑8601 timestamp at which `url` stops being valid. The URL is
            invalidated automatically and cannot be re-used after this time.
    BundleFieldData:
      type: object
      properties:
        doc_key:
          type: string
          description: |
            The key uniquely identifying this document in the Bundle (from the original BundleRequest)
        field_key:
          type: string
          description: >
            The key uniquely identifying the field in the Document (either as specified in the original
            DocumentRequestField in the DocumentRequest in BundleRequest, or as configured on the DocumentTemplate)
        label:
          type: string
          description: The label of the field (possibly blank)
        kind:
          type: string
          description: |
            The kind of field. Each field type serves a specific purpose:

            - `att` - **Attachment**: Allows signers to upload files (documents, images, etc.)
            - `cbg` - **Checkbox Group**: A group of related checkboxes where multiple options can be selected
            - `chk` - **Checkbox**: A single checkbox that can be checked or unchecked
            - `dat` - **Date**: A date picker field for entering dates
            - `ini` - **Initials**: A field for capturing the signer's initials
            - `inp` - **Text**: A single-line text input field for short text entries
            - `sel` - **Dropdown**: A dropdown/select field with predefined options
            - `sig` - **Signature**: A field for capturing the signer's electronic signature
            - `tms` - **Signing Date**: Automatically populated with the full timestamp when the document was signed
            - `txt` - **Multiline Text**: A multi-line text area for longer text entries
          enum:
            - att
            - cbg
            - chk
            - dat
            - ini
            - inp
            - sel
            - sig
            - tms
            - txt
        value:
          description: The value of the field.
          oneOf:
            - type: string
            - type: boolean
            - type: number
        filled_by:
          type: string
          description: >
            The Packet key of the signer that entered the value for this field. If the field value was an
            'initial_value' not edited by a signer, the value is 'initial'. If the field value was the default value
            configured on a DocumentTemplate, the filler is 'default'.
        packet_id:
          description: >
            The Packet id of the signer that entered the value for this field, or null if the field value was not filled
            in by a signer (ie, it was an initial_value or defaul value).
        attachments:
          description: An array of file attachments for an attachment field, or null
          type: array
          items:
            type: object
            properties:
              url:
                type: string
                format: url
                description: A URL that can be used temporarily to download the attachment file
              name:
                type: string
                description: File name of the attachment
              size:
                type: integer
                description: Size of the file, in bytes
              num:
                type: integer
                description: >
                  The order in which the file was added, if there we're multiple uploads for a single attachment field
                  (for instance, a photo for each page of a document taken with a webcam)
              ext:
                type: string
                description: The file extension
              is_image:
                type: boolean
                description: true if this attachment file is an image
    BundleData:
      type: array
      items:
        $ref: '#/components/schemas/BundleFieldData'
    Event:
      type: object
      properties:
        kind:
          type: string
          description: The kind of the event as a 2 character code
        description:
          type: string
          description: A brief desription of the event
        timestamp:
          type: string
          format: date-time
          description: The time at which the event occured
        packet_id:
          type: string
          format: uuid
          description: |
            The UUID of a Packet. Only present if the event is associated with a particular packet.
    Events:
      type: array
      items:
        $ref: '#/components/schemas/Event'
    Files:
      type: array
      items:
        type: object
        properties:
          file_url:
            type: string
            description: the URL from where the file can be downloaded
          expires:
            type: string
            description: The time at which the link expires, as an ISO 8601 formatted time
    BundleWithIncludes:
      allOf:
        - $ref: '#/components/schemas/Bundle'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/BundleData'
              description: |
                Form field data entered by signers. Only present when `include=data` is specified.
                Returns null if the bundle is not complete and early data access is not enabled.
            events:
              $ref: '#/components/schemas/Events'
              description: |
                Audit events for the bundle. Only present when `include=events` is specified.
            files:
              $ref: '#/components/schemas/Files'
              description: |
                Downloadable files for the bundle. Only present when `include=files` is specified.
                Returns null if the bundle is not complete with final documents or early file access is not enabled.
    BundlePatchRequest:
      type: object
      description: |
        Partial update payload for PATCH `/bundles/{bundleSlug}/`.

        Only Bundles in `dr` (Draft) or `se` (Sent) status can be updated.
      additionalProperties: false
      properties:
        team:
          type: string
          format: uuid
          nullable: true
          description: |
            Team UUID for this Bundle. Set to `null` to clear team assignment.
            Requires the Teams feature to be enabled and access to the specified team.
        expires:
          description: |
            Expiration value for this Bundle. Must be in the future.
            Accepts either full ISO 8601 datetime or date-only `YYYY-MM-DD`.
            For Sent (`se`) Bundles, updating this value changes the date while preserving
            the existing time-of-day.
          oneOf:
            - type: string
              format: date-time
              example: '2026-03-14T23:59:59Z'
            - type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
              example: '2026-03-14'
        cc_sender:
          type: boolean
          description: If true, CC the sender on completion notifications.
        cc_emails:
          type: array
          description: Email addresses to CC when the Bundle is complete.
          items:
            type: string
            format: email
            maxLength: 254
        send_reminders:
          type: boolean
          description: |
            Enable or disable signer reminder notifications.
            Requires the Reminders feature to be enabled.
        reminder_offset:
          type: integer
          minimum: 0
          maximum: 30
          description: |
            Number of days after send before the first reminder.
            Requires the Reminders feature to be enabled.
        reminder_interval:
          type: integer
          minimum: 0
          maximum: 30
          description: |
            Number of days between reminders.
            Requires the Reminders feature to be enabled.
        reminder_expires:
          type: integer
          minimum: 0
          maximum: 30
          description: |
            Number of days after send when reminders stop.
            Requires the Reminders feature to be enabled.
        owner:
          type: string
          format: uuid
          nullable: true
          description: |
            Owner user UUID for this Bundle. Set to `null` to clear owner assignment.
            Only account admins can update this field.
        signing_brand:
          type: string
          format: uuid
          nullable: true
          description: |
            Signing Brand UUID for this Bundle. Set to `null` to clear the signing brand.
            The signing brand must belong to the same account as the Bundle.
      example:
        owner: 7f3c9f91-7be8-4e7f-9965-77e2f0b781d8
        team: 22f23753-7fbe-42de-8eda-031423f965af
        signing_brand: a1b2c3d4-e5f6-7890-abcd-ef1234567890
        expires: '2026-03-14'
        reminder_offset: 1
        reminder_interval: 0
        reminder_expires: 0
        send_reminders: true
        cc_emails:
          - manager@example.com
          - admin@example.com
        cc_sender: false
    EmbedURL:
      type: object
      properties:
        url:
          type: string
          description: The URL which can be used in for embedded signing
        expires:
          type: string
          description: Timestamp indicating when url expires
          format: date-time
    File:
      type: object
      properties:
        file_url:
          type: string
          description: the URL from where the file can be downloaded
        expires:
          type: string
          description: The time at which the link expires, as an ISO 8601 formatted time
    DocumentTemplateField:
      allOf:
        - $ref: '#/components/schemas/DocumentField'
        - type: object
          properties:
            default_value:
              description: |
                A default value for the field. If editor_roles is empty, then this field
                is a read-only field that cannot be edited by any Signers. Note, validation
                (v_regex, v_min, v_max) is not applied to this value.

                Attachment type fields do not support default_value.

                For date fields, the date must be provided as a string in the format
                YYYY-MM-DD, like "2019-09-20".
              oneOf:
                - type: string
                - type: boolean
                - type: number
            editor_roles:
              type: array
              default: []
              description: |
                An array of role keys, as defined in 'roles', indicating which Roles can
                edit this field. By default the field will be required for any Role listed,
                meaning that when that Signer assigned to that Role is reviewing / signing the document,
                they cannot leave the field blank.

                Note oftentimes you will not want a Checkbox field to be required - because a
                required checkbox must be checked in order for a Signer to advance past the field.

                If the field should be editable, but optional for a given Role, prefix the key with a '-'.

                For example: ['role-1', '-role-2'] indicates that the field is required for role-1
                but optional for role-2.
              items:
                type: string
            data_flow_tag:
              type: string
              readOnly: true
              description: |
                An optional tag linking this field to a named data-flow slot in
                your integration. Only lowercase letters, digits, and underscores
                are allowed (pattern `^[a-z0-9_]+$`); at most 40 characters.
                When an account has a Data Flow Tag catalog configured, only
                catalog values are accepted.
              pattern: ^[a-z0-9_]+
              maxLength: 40
    DocumentTemplate:
      type: object
      required:
        - file
      properties:
        is_shared:
          type: boolean
          description: True if the Document Template is shared. False otherwise
        name:
          type: string
          description: >
            The name of the document. Defaults to the filename or the document when it was uploaded, but can be set to a
            human-friendly name.
        file_url:
          type: string
          description: The URL of the original file that serves as the basis for this Template
        roles:
          type: array
          items:
            type: object
            properties:
              key:
                type: string
                description: A string that is unique for this document which identifies this role
                pattern: ^[-\w]+$
                minLength: 2
                maxLength: 12
              label:
                type: string
                description: A human-friendly label for this role
        fields:
          type: array
          description: >
            An array of fields placed on the document. Note that DocumentTemplate fields are slightly different than
            DocumentRequest fields, having a `default_value` and `editor_roles` instead of `initial_value` and
            `editors`.
          items:
            $ref: '#/components/schemas/DocumentTemplateField'
        id:
          type: string
          format: uuid
          readOnly: true
          description: The unique identifier of the Document Template.
        teams:
          type: array
          readOnly: true
          description: |
            UUIDs of the teams this Document Template is assigned to, filtered
            to teams accessible to the authenticated user. Empty when teams are
            not enabled for the account.
          items:
            type: string
            format: uuid
        metadata:
          type: object
          description: |
            Developer-controlled key/value metadata attached to this Document
            Template. Shallow-merged on write: send key/value pairs to set or
            update individual keys, or send a top-level empty string (`""`) to
            wipe all metadata. Setting an individual value to `""` removes that
            key. Constraints: at most 50 keys; keys are non-empty strings of at
            most 40 characters; values are strings of at most 500 characters.
          additionalProperties:
            type: string
            maxLength: 500
    TemplatePreparationSessionRequest:
      type: object
      description: |
        Request body for `POST /templates/preparation_session/`. Pass
        `template_uuid` to open an existing Document Template for editing;
        omit it to start a new-template authoring flow. `team` and `library`
        are only applied when creating a new template (they are ignored when
        `template_uuid` is provided).
      properties:
        template_id:
          type: string
          format: uuid
          nullable: true
          description: |
            UUID of an existing Document Template to open for editing.
            Omit to start a new-template authoring flow.
        team:
          type: string
          format: uuid
          nullable: true
          description: |
            For new-template flows, the UUID of the team that should own the
            newly created template.
        library:
          type: string
          nullable: true
          description: |
            For new-template flows, the BUID of the template library
            (folder) the newly created template should be placed in.
        redirect_url:
          type: string
          format: uri
          maxLength: 400
          nullable: true
          description: |
            Optional URL the iframe will redirect to once the template
            preparation session is complete.
        metadata:
          type: object
          description: |
            Developer-controlled key/value metadata to attach to the template.
            In edit mode (`template_id` provided) the metadata is shallow-merged
            onto the existing template immediately. In new-template mode it is
            carried in the session payload and applied when the template is saved.
            Same constraints as `DocumentTemplate.metadata`: at most 50 keys,
            keys ≤ 40 characters, values ≤ 500 characters.
          additionalProperties:
            type: string
            maxLength: 500
    ContactChannel:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
          format: email
          maxLength: 254
        phone:
          type: string
          format: phone
          maxLength: 128
        kind:
          type: string
          description: em for email. mp for phone.
          enum:
            - em
            - mp
    Person:
      type: object
      properties:
        name:
          type: string
          description: The name of the person
        metadata:
          description: >
            Metadata to associate with this person. Metadata can be used in SmartFill to automatically populate
            documents. See SmartFill documentation for details.
          type: object
        id:
          type: string
          readOnly: true
          format: uuid
        is_user:
          type: boolean
          readOnly: true
          description: True if this Person is associated with a Blueink User
        channels:
          type: array
          items:
            $ref: '#/components/schemas/ContactChannel'
    Persons:
      type: array
      items:
        $ref: '#/components/schemas/Person'
    WebhookExtraHeader:
      type: object
      properties:
        id:
          type: string
          format: uuid
        webhook:
          type: string
          format: uuid
        name:
          type: string
          maxLength: 80
          description: must adhere to RFC 7230
        value:
          type: string
          maxLength: 240
          description: must adhere to RFC 7230
        order:
          type: integer
          default: 1
    Webhook:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          description: Human-readable name for the webhook. Must be unique within the account.
        url:
          type: string
          format: url
          description: should be the full URL, including http/https
        enabled:
          type: boolean
          default: true
        json:
          type: boolean
          default: true
        event_types:
          type: array
          description: types of events that will fire the webhook
          items:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
              - packet_declined
        extra_headers:
          type: array
          items:
            $ref: '#/components/schemas/WebhookExtraHeader'
    Webhooks:
      type: array
      items:
        $ref: '#/components/schemas/Webhook'
    WebhookRequest:
      type: object
      description: Schema for creating a webhook (excludes server-generated fields like id and extra_headers)
      properties:
        name:
          type: string
          description: Human-readable name for the webhook. Must be unique within the account.
        url:
          type: string
          format: url
          description: should be the full URL, including http/https
        enabled:
          type: boolean
          default: true
        json:
          type: boolean
          default: true
        event_types:
          type: array
          description: types of events that will fire the webhook
          items:
            type: string
            enum:
              - bundle_sent
              - bundle_complete
              - bundle_docs_ready
              - bundle_error
              - bundle_cancelled
              - packet_viewed
              - packet_complete
              - packet_declined
      required:
        - name
        - url
        - event_types
    WebhookExtraHeaders:
      type: array
      items:
        $ref: '#/components/schemas/WebhookExtraHeader'
    WebhookDelivery:
      type: object
      properties:
        pk:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
          description: when the delivery attempt occurred (the start of the attempt, not when it failed, e.g for a timeout)
        status:
          type: integer
          description: status message of the response, or 0 if no status
          default: 0
        message:
          type: string
          description: a message describing any issues
    WebhookEvent:
      type: object
      properties:
        pk:
          type: string
          format: uuid
        webhook:
          type: string
          format: uuid
          description: UUID identifying which webhook the Event belongs to
        event_type:
          type: string
          maxLength: 24
          enum:
            - bundle_sent
            - bundle_complete
            - bundle_docs_ready
            - bundle_error
            - bundle_cancelled
            - packet_viewed
            - packet_complete
        created:
          type: string
          format: date-time
        status:
          type: integer
          default: 0
          description: the status code of the last response from webhook endpoint. 0 indicates no response received
        success:
          type: boolean
          default: false
        payload:
          type: string
          description: the payload to send on delivery; json
        deliveries:
          type: array
          items:
            $ref: '#/components/schemas/WebhookDelivery'
    WebhookEvents:
      type: array
      items:
        $ref: '#/components/schemas/WebhookEvent'
    WebhookSecret:
      type: object
      properties:
        secret:
          type: string
          format: b58
        create_date:
          type: string
          format: date-time
    EnvelopeTemplate:
      type: object
      properties:
        id:
          type: string
          description: The unique slug identifier for this Envelope Template
          readOnly: true
        created:
          type: string
          format: date-time
          description: The timestamp when this Envelope Template was created
          readOnly: true
        name:
          type: string
          description: The name of the Envelope Template
          readOnly: true
        description:
          type: string
          description: A description of what this Envelope Template is used for
          readOnly: true
        is_shared:
          type: boolean
          description: True if this Envelope Template is shared across the account
          readOnly: true
        is_portal:
          type: boolean
          description: True if this Envelope Template is configured as a portal (smart link enabled)
          readOnly: true
        allow_direct_signing:
          type: boolean
          description: True if this Envelope Template allows direct signing without authentication
          readOnly: true
        documents:
          type: array
          description: An array of documents included in this Envelope Template
          readOnly: true
          items:
            type: object
            properties:
              key:
                type: string
                description: The unique key identifying this document within the template
              name:
                type: string
                description: The name of the document
              order:
                type: integer
                description: The order in which this document appears in the template
        signers:
          type: array
          description: An array of signer roles defined in this Envelope Template
          readOnly: true
          items:
            type: object
            properties:
              key:
                type: string
                description: The unique key identifying this signer role within the template
              label:
                type: string
                description: A human-readable label for this signer role
              order:
                type: integer
                description: The order in which this signer should sign (if in_order is enabled)
              auth_sms:
                type: boolean
                description: True if SMS authentication is required for this signer role
              auth_selfie:
                type: boolean
                description: True if selfie authentication is required for this signer role
              auth_id:
                type: boolean
                description: True if ID verification is required for this signer role
        smart_link_url:
          type: string
          description: The smart link URL if this template is configured as a portal, empty string otherwise
          readOnly: true
    EnvelopeTemplates:
      type: array
      items:
        $ref: '#/components/schemas/EnvelopeTemplate'
    VerifyRequest:
      type: object
      required:
        - hash
      properties:
        hash:
          type: string
          description: |
            A hex-encoded SHA‑256 digest of the PDF file being verified
            (64 lowercase hex characters). Case is normalised server-side.
          pattern: ^[a-fA-F0-9]{64}$
          example: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
    VerifyResponse:
      type: object
      required:
        - status
        - message
        - sha256
      properties:
        status:
          type: string
          enum:
            - verified
            - invalid
          description: |
            Verification result.

            - `verified` — the supplied hash matches a signed PDF, combined PDF,
              or Certificate of Execution produced by Blueink for a completed Bundle.
            - `invalid` — the hash does not match any document on record.
        message:
          type: string
          description: A human-readable message describing the verification result.
        sha256:
          type: string
          description: The normalised (lowercase) hash that was verified.
        document_type:
          type: string
          enum:
            - signed_pdf
            - combined_pdf
            - coe_pdf
          description: |
            Present only when `status` is `verified`. Identifies which kind of
            Blueink-produced document the hash matched:

            - `signed_pdf` — a per-document signed PDF.
            - `combined_pdf` — the combined PDF for the whole Bundle.
            - `coe_pdf` — the Certificate of Execution for a Packet.
        signed_at:
          type: string
          format: date-time
          nullable: true
          description: |
            Present only when `status` is `verified`. ISO‑8601 timestamp at which
            the matching document was generated. May be `null` if no timestamp is
            available on the underlying file record.
        envelope:
          type: object
          description: |
            Present only when `status` is `verified`. Limited, non-identifying
            information about the Bundle the document was generated for.
          properties:
            bundle_slug:
              type: string
              description: The slug of the Bundle.
            status:
              type: string
              description: Human-readable Bundle status (e.g. `Complete`).
            sent:
              type: string
              format: date-time
              nullable: true
            completed_at:
              type: string
              format: date-time
              nullable: true
  responses:
    400BadRequest:
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    404NotFound:
      description: Not found response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  parameters:
    bundleSlug:
      name: bundleSlug
      in: path
      description: The slug that uniquely identifies the Bundle
      required: true
      schema:
        type: string
    include:
      name: include
      in: query
      description: |
        Comma-separated list of additional data to include in the response.
        Allows you to retrieve related information in a single request instead of making separate API calls.

        Supported values:
        - `data`: Include form field data entered by signers (same as /data endpoint)
        - `events`: Include audit events for the bundle (same as /events endpoint)
        - `files`: Include downloadable files for the bundle (same as /files endpoint)

        Examples:
        - `?include=data` - Include only form data
        - `?include=events,files` - Include both events and files
        - `?include=data,events,files` - Include all additional data
      required: false
      schema:
        type: string
        pattern: ^(data|events|files)(,(data|events|files))*$
        example: data,events,files
    packetId:
      name: packetId
      in: path
      description: The slug that uniquely identifies the Packet
      required: true
      schema:
        type: string
    templateId:
      name: templateId
      in: path
      description: The ID that uniquely identifies the Template
      required: true
      schema:
        type: string
        format: uuid
    personId:
      name: personId
      in: path
      description: The ID that uniquely identifies the Person
      required: true
      schema:
        type: string
        format: uuid
    webhookId:
      name: webhookId
      in: path
      description: The ID that uniquely identifies the Webhook
      required: true
      schema:
        type: string
        format: uuid
    webhookExtraHeaderId:
      name: webhookExtraHeaderId
      in: path
      description: The ID that uniquely identifies the WebhookExtraHeader
      required: true
      schema:
        type: string
        format: uuid
    webhookEventId:
      name: webhookEventId
      in: path
      description: The ID that uniquely identifies the WebhookEvent
      required: true
      schema:
        type: string
        format: uuid
    webhookDeliveryId:
      name: webhookDeliveryId
      in: path
      description: The ID that uniquely identifies the WebhookDelivery
      required: true
      schema:
        type: string
        format: uuid
    envelopeTemplateId:
      name: envelopeTemplateId
      in: path
      description: The slug that uniquely identifies the Envelope Template
      required: true
      schema:
        type: string
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >
        Authenticated requests require an `Authorization` header with the value `Token <your-api-key>`. Example:
        `Authorization: Token abcd1234`.
