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

# Execute Company Verification (sync)

> Submit company data for synchronous registry lookup and screening. The API
performs company registry verification, director screening, and UBO screening
in a single call.

Include the `X-SYNC-TIMEOUT` header to control how long the API blocks before
returning. If checks complete within the timeout, a full `VerificationReport` is
returned (200). If the timeout is exceeded, partial results with pull/start
tokens are returned (202) so you can retrieve the rest asynchronously.




## OpenAPI

````yaml /zenoo-api-openapi.yaml post /api/gateway/execute/{project_hash}/api
openapi: 3.1.0
info:
  title: Zenoo API
  version: 3.0.0
  summary: >-
    Unified compliance platform API — orchestration, case management, and
    screening
  description: >
    > **Welcome to the Zenoo API v3**

    >

    > Zenoo is a unified compliance platform that combines verification
    orchestration

    > (Studio) with case management (CLM) through a single API surface. Submit
    entity

    > data, run checks, manage investigations, and track compliance decisions —
    all

    > through one integration.


    ## Platform Architecture


    ```

    Your System ──► Zenoo API v3
                       │
                       ├── Studio (Orchestration)
                       │     ├── Flow execution (sync / async)
                       │     ├── Provider routing (WorldCheck, Sumsub, ComplyAdvantage)
                       │     └── Structured results with risk scoring
                       │
                       └── CLM (Case Management)
                             ├── Case lifecycle (create → investigate → close)
                             ├── Alert triage (auto-priority, SLA tracking)
                             ├── Risk assessment (4-dimension scoring)
                             ├── Audit trail (immutable compliance log)
                             └── AI-powered research and disposition
    ```


    ## Key Concepts


    | Concept | Description | Token Prefix |

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

    | **Flow** | Orchestration template that defines which checks to run |
    `flw_` |

    | **Case** | Investigation container — groups entities, alerts, and checks |
    `cas_` |

    | **Entity** | Person or company under investigation | `ent_` |

    | **Alert** | Issue requiring analyst review (PEP match, sanctions hit,
    etc.) | `alt_` |

    | **Check** | Verification action (screening, identity, document, company) |
    `chk_` |

    | **Risk Assessment** | 4-dimension risk score with tiered classification |
    `rsk_` |

    | **Comment** | Analyst note, decision record, or system event on a case |
    `cmt_` |

    | **Audit Log** | Immutable record of every action taken on the platform |
    `aud_` |


    ## Authentication


    All requests require authentication via one of two methods:


    | Method | Header | Use Case |

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

    | **API Key** | `X-API-KEY: <your-key>` | Server-to-server integrations |

    | **OAuth 2.0** | `Authorization: Bearer <token>` | Application-level access
    with scoped permissions |


    API keys are project-scoped. Staging and production use different keys.

    Never expose API keys in client-side code.


    ## Pagination


    All list endpoints use cursor-based pagination:


    ```json

    {
      "data": [...],
      "meta": {
        "cursor": "eyJpZCI6ImNhc18xMjM0In0=",
        "has_more": true
      }
    }

    ```


    Pass the `cursor` value as a query parameter to fetch the next page.

    Default page size is 25; maximum is 100.


    ## Idempotency


    All mutation endpoints (POST, PATCH, DELETE) support the `Idempotency-Key`
    header.

    Send the same key within 24 hours to safely retry requests without duplicate
    side effects.


    ## Rate Limits


    | Plan | Requests/min | Burst |

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

    | Starter | 60 | 10 |

    | Professional | 300 | 50 |

    | Enterprise | 1000 | 200 |


    Rate limit headers are included in every response:

    `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`.


    ## Versioning


    This API follows semantic versioning. The current version is **v3.0.0**.

    Breaking changes are communicated via email and changelog at least 30 days
    in advance.
  contact:
    name: Zenoo Developer Support
    email: support@zenoo.com
    url: https://zenoo.com
  license:
    name: Proprietary
    url: https://zenoo.com/terms
servers:
  - url: https://instance.prod.onboardapp.io
    description: Production (replace "instance" with your subdomain)
  - url: https://instance.staging.onboardapp.io
    description: Staging (replace "instance" with your subdomain)
  - url: https://api.zenoo.com
    description: Case Management API
security:
  - ApiKeyAuth: []
tags:
  - name: Flow API
    description: >
      Submit entity data for compliance verification — company registry lookups,
      person

      identity checks, and AML screening. The Flow API supports three flow

      types, each available in synchronous and asynchronous modes.


      ## Flow Types


      | Type | Endpoint Pattern | Description |

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

      | **Company** | `/api/gateway/execute/{project_hash}/api` (sync) |
      Registry lookup + director/UBO screening |

      | **Company** | `/api/gateway/execute/{project_hash}/init` (async) | Same
      checks, returns tokens immediately |

      | **Person** | `/api/gateway/execute/{project_hash}/kyc/api` (sync) |
      Identity + screening (server-side) |

      | **Person** | `/api/gateway/execute/{project_hash}/kyc/init` (async) |
      Identity + document capture + biometrics |

      | **Screening** | `/api/gateway/execute/{project_hash}/screening/api` |
      Standalone PEP/sanctions/adverse media check |

      | **Results** | `GET /api/gateway/sharable-payload/{pull_token}` |
      Retrieve async verification results |


      ## Capabilities


      | Capability | Description |

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

      | **Sync execution** | Block until all checks complete (with configurable
      timeout via `X-SYNC-TIMEOUT`) |

      | **Async execution** | Initiate verification, retrieve results via pull
      token or webhook |

      | **Multi-provider** | Route checks across WorldCheck, Sumsub,
      ComplyAdvantage, and more |

      | **Idempotency** | Use `external_reference` to prevent duplicate
      verifications |

      | **Verification URLs** | Generate hosted verification journeys for
      document capture + biometrics |


      ## Execution Models


      ```

      Sync:   POST /api (or /kyc/api) ──► Checks Run ──► Full Results Returned
      (200)
                                       └──► Timeout ──► Partial Results + Tokens (202)

      Async:  POST /init (or /kyc/init) ──► Tokens Returned (200)
                                            ├──► GET /sharable-payload/{pull} ──► Results
                                            └──► Webhook delivery (recommended)
      ```


      > **Use sync** for server-to-server checks (screening, registry lookups)
      where you need results immediately.

      > **Use async** for client-facing journeys (document capture, biometric
      liveness) or when processing may exceed timeout.
  - name: Entities
    description: >
      Manage person and company entities under compliance investigation.
      Entities are

      the subjects of verification — they belong to cases, receive checks, and
      generate

      alerts when screening matches are found.


      ## Capabilities


      | Capability | Description |

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

      | **Create** | Register a person or company entity with identifying data |

      | **Update** | Patch entity attributes as new information becomes
      available |

      | **List checks** | View all verification checks associated with an entity
      |

      | **List alerts** | View all alerts generated from entity screening
      results |


      ## Entity Types


      | Type | Key Fields | Typical Checks |

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

      | **Person** | first_name, last_name, date_of_birth, nationality |
      Identity, Screening, Document |

      | **Company** | company_name, registration_number, country | Company
      registry, Corporate screening |


      ## Entity Roles


      | Role | Description |

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

      | `Primary` | The main subject of the case |

      | `UBO` | Ultimate Beneficial Owner (>=25% ownership) |

      | `Director` | Company director or officer |

      | `Shareholder` | Company shareholder below UBO threshold |
  - name: Cases
    description: >
      Manage the full lifecycle of compliance investigation cases. A case groups
      entities,

      alerts, checks, risk assessments, and audit trails into a single
      investigation unit.


      ## Capabilities


      | Capability | Description |

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

      | **Lifecycle management** | Create, update, close, escalate cases |

      | **Entity management** | Add persons and companies to a case |

      | **Alert aggregation** | View all alerts across case entities |

      | **Risk assessment** | Calculate and manage 4-dimension risk scores |

      | **Collaboration** | Comments, reviewers, and compliance reports |

      | **Audit trail** | Immutable timeline of all case actions |


      ## Case Lifecycle


      ```

      New ──► In Progress ──► In Review ──► Closed
        │         │               │
        │         ├──► Client Input ──┘
        │         │
        │         └──► Internal Review ──┘
        │
        └──► Escalated
      ```


      ## Case Types


      | Type | Description | Typical Duration |

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

      | `Onboarding` | New customer due diligence | 1-5 business days |

      | `Review` | Periodic review of existing customer | 5-15 business days |

      | `Perpetual` | Ongoing monitoring case (no fixed end) | Continuous |
  - name: Alerts
    description: >
      Triage, investigate, and resolve compliance alerts. Alerts are generated
      automatically

      when screening checks find matches (PEP, sanctions, adverse media) or when
      verification

      checks fail. Each alert requires analyst review and resolution.


      ## Capabilities


      | Capability | Description |

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

      | **Triage** | Acknowledge, assign, and prioritize alerts |

      | **Resolution** | Resolve as true positive, false positive, or escalate |

      | **Bulk operations** | Resolve, acknowledge, or assign multiple alerts at
      once |

      | **AI research** | Trigger AI-powered research for deeper investigation |

      | **SLA tracking** | Automatic priority scoring and deadline management |


      ## Alert Lifecycle


      ```

      Open ──► Acknowledged ──► Resolved
        │           │              │
        │           │         (False Positive)
        │           │
        └──► Escalated
      ```


      ## Alert Categories


      | Category | Source | Typical Priority |

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

      | `PEP Match` | Screening provider | High |

      | `Sanctions Hit` | Screening provider | Critical |

      | `Adverse Media` | Screening provider | Medium-High |

      | `Name Mismatch` | Identity check | Medium |

      | `DOB Mismatch` | Identity check | Medium |

      | `Watchlist Match` | Screening provider | High |

      | `API Failure` | System | Low |
  - name: Checks
    description: >
      Execute and manage verification checks on entities. Checks are the atomic
      units

      of verification — each check runs against a specific provider and produces
      a

      pass/fail/refer result.


      ## Capabilities


      | Capability | Description |

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

      | **Execute** | Trigger a check to run against its configured provider |

      | **Waive** | Mark a check as waived with a documented reason |

      | **Reuse** | Automatically reuse valid results from prior checks |

      | **Status tracking** | Monitor check progress through its lifecycle |


      ## Check Categories


      | Category | Examples | Typical Providers |

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

      | `Identity` | Document OCR, biometric liveness, face match | Sumsub |

      | `Screening` | PEP, sanctions, adverse media, watchlist | WorldCheck,
      ComplyAdvantage |

      | `Company` | Registry lookup, corporate structure | Registry providers |

      | `Financial` | Source of funds, transaction monitoring | Financial data
      providers |

      | `EDD` | Enhanced due diligence, deep research | AI services |


      ## Check Lifecycle


      ```

      Pending ──► Queued ──► In Progress ──► Complete (Pass/Fail/Refer)
                                  │
                                  ├──► Awaiting Document
                                  ├──► Awaiting Client
                                  ├──► Failed
                                  ├──► Retry Scheduled
                                  └──► Cancelled
      ```
  - name: Risk Assessments
    description: >
      Manage risk assessments that score entities across four dimensions. Risk
      assessments

      produce an overall score and tier classification (High/Medium/Low) used
      for

      due diligence path routing and SLA assignment.


      ## Capabilities


      | Capability | Description |

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

      | **Calculate** | Run the risk model against case data to produce a score
      |

      | **Approve** | Senior reviewer approves the assessment |

      | **Override** | Override the calculated tier with justification |


      ## Risk Dimensions


      | Dimension | Weight | Factors |

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

      | `customer` | 30% | Entity type, PEP status, sanctions, adverse media |

      | `geographic` | 25% | Country risk, FATF status, jurisdiction |

      | `product_service` | 25% | Product complexity, regulatory exposure |

      | `transaction` | 20% | Volume, frequency, unusual patterns |


      ## Risk Tiers


      | Tier | Score Range | Due Diligence Path | Review Frequency |

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

      | `High` | 70-100 | EDD (Enhanced) | 6 months |

      | `Medium` | 40-69 | CDD (Standard) | 12 months |

      | `Low` | 0-39 | SDD (Simplified) | 24-36 months |
  - name: Audit Trail
    description: >
      Access the immutable audit log that records every action taken on the
      platform.

      Audit logs are append-only and cannot be modified or deleted, ensuring
      full

      regulatory compliance and traceability.


      ## Capabilities


      | Capability | Description |

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

      | **Query** | Filter logs by event type, actor, target, and date range |

      | **Case timeline** | View the complete history of a specific case |

      | **Compliance export** | Generate audit reports for regulatory
      submissions |


      ## Event Types


      | Category | Events |

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

      | **Case** | case.created, case.status_changed, case.closed,
      case.escalated |

      | **Alert** | alert.created, alert.acknowledged, alert.resolved,
      alert.escalated |

      | **Check** | check.executed, check.completed, check.failed, check.waived
      |

      | **Risk** | risk_assessment.calculated, risk_assessment.approved,
      risk_assessment.overridden |

      | **Entity** | entity.created, entity.updated, entity.added_to_case |
  - name: Analytics
    description: >
      Access compliance metrics and statistics for dashboards, reporting, and
      operational

      monitoring. Analytics endpoints provide aggregated data across cases,
      alerts,

      and checks.


      ## Capabilities


      | Capability | Description |

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

      | **Summary metrics** | Key compliance KPIs (open cases, pending alerts,
      SLA health) |

      | **Alert statistics** | Alert volume, resolution rates, category
      breakdown |

      | **Case statistics** | Case throughput, aging, type distribution |
  - name: Webhooks
    description: >
      Register and manage webhook endpoints to receive real-time notifications
      when

      events occur on the platform. Webhook payloads are signed with HMAC-SHA256

      for verification.


      ## Events


      | Event | Trigger | Typical Latency |

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

      | `case.created` | New case is created | <5 seconds |

      | `case.status_changed` | Case status transitions | <5 seconds |

      | `case.closed` | Case is closed | <5 seconds |

      | `case.escalated` | Case is escalated | <5 seconds |

      | `alert.created` | New alert is generated | <5 seconds |

      | `alert.resolved` | Alert is resolved | <5 seconds |

      | `alert.escalated` | Alert is escalated | <5 seconds |

      | `check.completed` | Check finishes successfully | <5 seconds |

      | `check.failed` | Check fails after retries | After last retry |

      | `risk_assessment.completed` | Risk score calculated | <5 seconds |

      | `risk_assessment.approved` | Assessment approved | <5 seconds |

      | `sla.warning` | SLA deadline approaching | At warning threshold |

      | `sla.breached` | SLA deadline passed | At breach time |


      ## Signature Verification


      Every webhook includes an `X-Zenoo-Signature` header containing `sha256=`
      followed

      by the hex-encoded HMAC-SHA256 digest of the raw request body, computed
      with your

      webhook secret.


      **Verify signatures using constant-time comparison:**


      | Language | Function |

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

      | Node.js | `crypto.timingSafeEqual()` |

      | Python | `hmac.compare_digest()` |

      | Java | `MessageDigest.isEqual()` |

      | Go | `hmac.Equal()` |


      ## Retry Schedule


      | Attempt | Delay |

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

      | 1st retry | 1 minute |

      | 2nd retry | 5 minutes |

      | 3rd retry | 30 minutes |

      | 4th retry | 1 hour |

      | 5th-168th | Every 1 hour for 7 days |


      After 7 days of consecutive failures, the webhook is marked as
      undeliverable.
  - name: Comments
    description: >
      Manage discussion and collaboration on cases. Comments support analyst
      notes,

      formal decisions, system-generated events, and user mentions for team
      coordination.


      ## Comment Types


      | Type | Description | Created By |

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

      | `Comment` | Free-form analyst note or observation | Analyst |

      | `Decision` | Formal decision record (approve, decline, escalate) |
      Senior reviewer |

      | `Note` | Internal note not visible to external parties | Any user |

      | `System` | Auto-generated event record (status change, assignment) |
      System |
paths:
  /api/gateway/execute/{project_hash}/api:
    post:
      tags:
        - Flow API
      summary: Execute Company Verification (sync)
      description: >
        Submit company data for synchronous registry lookup and screening. The
        API

        performs company registry verification, director screening, and UBO
        screening

        in a single call.


        Include the `X-SYNC-TIMEOUT` header to control how long the API blocks
        before

        returning. If checks complete within the timeout, a full
        `VerificationReport` is

        returned (200). If the timeout is exceeded, partial results with
        pull/start

        tokens are returned (202) so you can retrieve the rest asynchronously.
      operationId: executeCompanyVerification
      parameters:
        - name: project_hash
          in: path
          required: true
          description: Project identifier from Zenoo Studio.
          schema:
            type: string
        - name: X-API-KEY
          in: header
          required: true
          description: Project-scoped API key.
          schema:
            type: string
        - name: X-SYNC-TIMEOUT
          in: header
          description: >
            Sync timeout in milliseconds. The API blocks until all checks
            complete or

            the timeout is reached. Recommended: `30000` for registry-only,

            `60000` for registry + screening. Range: 5000-120000.
          schema:
            type: integer
            minimum: 5000
            maximum: 120000
        - name: Idempotency-Key
          in: header
          description: >-
            Unique key for idempotent request handling. Same key within 24 hours
            returns the original response.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyVerificationRequest'
      responses:
        '200':
          description: All checks completed within timeout. Full compliance report.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationReport'
        '202':
          description: >
            Sync timeout exceeded. Partial results returned with tokens for
            retrieving

            the remaining data asynchronously.
          content:
            application/json:
              schema:
                type: object
                properties:
                  tokens:
                    type: object
                    properties:
                      pull:
                        type: string
                        description: >-
                          Token for retrieving full results via `GET
                          /api/gateway/sharable-payload/{pull}`.
                      start:
                        type: string
                        nullable: true
                        description: Start token (null for company verification).
                  data:
                    type: object
                    description: Partial results available so far.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  schemas:
    CompanyVerificationRequest:
      type: object
      description: >
        Request body for Company Verification. Zenoo accepts three tiers of data
        —

        more data produces richer results and fewer false positives.


        | Tier | Fields | Result Quality |

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

        | **Minimum** | company_name, registration_number, country | Registry
        lookup + company screening |

        | **Standard** | + directors[], ubos[], address | Individual screening
        for each person |

        | **Full** | + external_reference, annual_revenue, sic_codes |
        Idempotency, enriched risk scoring |
      properties:
        company_name:
          type: string
          description: Legal name as registered with the company registry.
          example: Acme Holdings Ltd
        registration_number:
          type: string
          description: Official company registration number.
          example: '12345678'
        country:
          type: string
          description: Country of incorporation. ISO 3166-1 alpha-2 code.
          example: GB
        company_type:
          type: string
          description: >-
            Legal entity type (e.g., `Private Limited Company (Ltd)`, `PLC`,
            `LLP`).
        incorporation_date:
          type: string
          format: date
          description: Date of incorporation. ISO 8601 format (YYYY-MM-DD).
        industry:
          type: string
          description: Industry sector or classification.
        address_line_1:
          type: string
          description: Registered address street.
        city:
          type: string
          description: Registered address city.
        postcode:
          type: string
          description: Postal code.
        annual_revenue:
          type: string
          description: Annual revenue in base currency. Pass as a string.
        employee_count:
          type: string
          description: Number of employees. Pass as a string.
        sic_codes:
          type: string
          description: SIC codes, comma-separated (e.g., "64110,64191").
        status:
          type: string
          description: 'Current company status: `Active`, `Dissolved`, `Struck Off`.'
        external_reference:
          type: string
          description: >
            Your internal reference ID. Enables idempotency — submitting the
            same

            external_reference returns the existing result without creating a
            duplicate.
          maxLength: 255
        directors:
          type: array
          description: >-
            Known directors. Each person is automatically screened for
            PEP/sanctions.
          items:
            $ref: '#/components/schemas/DirectorInput'
        ubos:
          type: array
          description: Known beneficial owners. Each person is automatically screened.
          items:
            $ref: '#/components/schemas/UBOInput'
      required:
        - company_name
        - registration_number
        - country
    VerificationReport:
      type: object
      description: |
        Top-level verification result from the pull endpoint or sync response.
        Contains overall verdict, risk assessment, and detailed check results.
      properties:
        case_reference:
          type: string
          description: Zenoo's unique case identifier.
          example: AML-2026-0042
        external_reference:
          type: string
          description: Your reference ID, echoed back from the request.
        processing_status:
          type: string
          enum:
            - complete
            - processing
            - failed
          description: Current processing state.
        overall_verdict:
          type: string
          enum:
            - Pass
            - Refer
            - Fail
          description: Aggregated verification outcome.
        risk_tier:
          type: string
          enum:
            - High
            - Medium
            - Low
          description: Assessed risk level.
        completed_at:
          type: string
          format: date-time
          description: ISO 8601 completion timestamp.
        next_review_date:
          type: string
          format: date
          description: Recommended next review date.
        company:
          type: object
          description: Registry-verified company data (Company Verification only).
        screening:
          type: object
          description: Screening summary with PEP/sanctions/adverse media status.
        directors:
          type: array
          description: Director screening results (Company Verification only).
          items:
            type: object
        beneficial_owners:
          type: array
          description: UBO screening results (Company Verification only).
          items:
            type: object
        identity:
          type: object
          description: Identity verification result (Person Verification only).
        document:
          type: object
          description: Document verification result (Person Verification only).
        biometric:
          type: object
          description: Biometric liveness result (Person Verification only).
        risk_assessment:
          type: object
          description: Risk score breakdown.
        checks_summary:
          type: object
          description: Summary of all checks performed.
        compliance_metadata:
          type: object
          description: CDD/EDD status and case URL.
    DirectorInput:
      type: object
      description: Director data for Company Verification.
      properties:
        first_name:
          type: string
        last_name:
          type: string
        date_of_birth:
          type: string
          format: date
          description: ISO 8601 date. Strongly recommended for screening accuracy.
        nationality:
          type: string
          description: ISO 3166-1 alpha-2 code.
        role:
          type: string
          description: 'Role: `Director`, `Secretary`, `Chair`.'
        appointed_date:
          type: string
          format: date
        zenoo_entity_id:
          type: string
          description: Your entity reference for correlation across verifications.
    UBOInput:
      type: object
      description: Beneficial owner data for Company Verification.
      properties:
        first_name:
          type: string
        last_name:
          type: string
        date_of_birth:
          type: string
          format: date
        nationality:
          type: string
          description: ISO 3166-1 alpha-2 code.
        ownership_percentage:
          type: number
          description: Ownership stake as a whole number, 0-100.
        role:
          type: string
          description: 'Role: `UBO`, `Shareholder`.'
        zenoo_entity_id:
          type: string
    ErrorResponse:
      type: object
      description: >
        Standard error response. All errors include a machine-readable `code`,

        human-readable `message`, and a `request_id` for support
        troubleshooting.
      properties:
        error:
          type: object
          required:
            - code
            - message
            - request_id
          properties:
            code:
              type: string
              description: >
                Machine-readable error code. Use this for programmatic error
                handling.


                | Code | HTTP | Description | Retry? |

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

                | `VALIDATION_ERROR` | 400 | Malformed request body or
                parameters | No |

                | `INVALID_JSON` | 400 | Request body is not valid JSON | No |

                | `UNAUTHORIZED` | 401 | Invalid or missing API key | No |

                | `FORBIDDEN` | 403 | Insufficient permissions | No |

                | `NOT_FOUND` | 404 | Resource does not exist | No |

                | `TOKEN_EXPIRED` | 404 | Pull or start token has expired | No |

                | `RATE_LIMITED` | 429 | Rate limit exceeded | Yes (after reset)
                |

                | `INTERNAL_ERROR` | 500 | Unexpected server error | Yes (with
                backoff) |

                | `PROVIDER_ERROR` | 502 | External provider failure | Yes (with
                backoff) |

                | `SERVICE_UNAVAILABLE` | 503 | Service temporarily unavailable
                | Yes (with backoff) |
              enum:
                - VALIDATION_ERROR
                - INVALID_JSON
                - UNAUTHORIZED
                - FORBIDDEN
                - NOT_FOUND
                - TOKEN_EXPIRED
                - RATE_LIMITED
                - INTERNAL_ERROR
                - PROVIDER_ERROR
                - SERVICE_UNAVAILABLE
            message:
              type: string
              description: Human-readable error description.
            details:
              type: array
              description: Field-level validation errors (present for `validation_error`).
              items:
                type: object
                properties:
                  field:
                    type: string
                    description: JSON path to the invalid field.
                  message:
                    type: string
                    description: Description of the validation failure.
                  code:
                    type: string
                    description: >-
                      Field-level error code (e.g., `required`,
                      `invalid_format`).
            request_id:
              type: string
              description: >
                Unique request identifier. Include this when contacting Zenoo
                support

                for faster issue resolution.
              example: req_9k4m2n1p3q
  responses:
    BadRequest:
      description: >-
        Invalid request — check the error details for field-level validation
        errors.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing or invalid authentication credentials.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: The requested resource does not exist. Verify the token is correct.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    TooManyRequests:
      description: >-
        Rate limit exceeded. Retry after the time indicated in the
        `X-RateLimit-Reset` header.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
    InternalError:
      description: >-
        Unexpected server error. Include the `request_id` from the error
        response when contacting support.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  headers:
    X-RateLimit-Limit:
      description: Maximum requests allowed per minute for your plan.
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests remaining in the current rate limit window.
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix timestamp when the rate limit window resets.
      schema:
        type: integer
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: |
        Project-scoped API key for server-to-server authentication.
        Obtain keys from the Zenoo dashboard under Project Settings > API Keys.
        Staging and production environments use separate keys.

````