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

# Patch diagnostics/routing/admin fields



## OpenAPI

````yaml /api-reference/openapi.json patch /intent/{intent_id}
openapi: 3.1.0
info:
  title: composerID Intent API
  version: 1.0.0-draft
  summary: >-
    Publish a decision into any destination system of record, under one Intent
    ID.
  description: >
    The composerID Intent API: mint an intent at the decision, plan its

    destinations, preflight against a tenant's own requirements, publish
    idempotently,

    and reconcile drift, with every step on an append-only timeline under one
    Intent ID.


    **Status.** This is the documented contract, served today by the reference
    sandbox

    (`service/` in the composerID repository) over mock destination tenants. The

    production service behind `https://api.composer.id` is in build; nothing
    here is a

    claim that it is live. The sandbox implements this document exactly, so a
    client

    generated from it works against the sandbox now and against production
    unchanged.


    **Authentication.** Bearer token on every request (`Authorization: Bearer

    <token>`). Production clients use OAuth 2.0 client credentials: exchange a

    `client_id` and `client_secret` at `POST /v1/oauth/token` for a token that

    expires in an hour and carries only the scopes the client was granted

    (`intents:read`, `intents:write`, `publish`, `reconcile`, `passthrough`,

    `destinations:read`); a token without the scope a route needs gets 403

    `insufficient_scope`. Personal sandbox API keys are also accepted as bearer

    tokens and carry every scope. All comparisons are constant-time. Destination

    credentials are never supplied by the caller: they are held per tenant and

    injected by the adapter.


    **Sandbox credentials.** The hosted sandbox issues its own: `POST

    /v1/sandbox/keys` (no authentication, rate-limited per caller address)

    creates a tenant with a personal API key, an OAuth client and a webhook

    signing key, shown once and expiring together. Each tenant sees only the

    intents it minted. The local run prints a key at startup instead. The

    production service will not expose this route.

    The one route that carries no bearer token is `POST
    /v1/webhooks/{platform}`:

    the caller is a destination platform, so the delivery authenticates by its

    `X-Signature-HMAC-SHA256-{n}` header (Base64 HMAC-SHA256 over the raw body,

    any active signing key, timing-safe), the same convention composerID's own

    outbound webhooks use.


    **Idempotency.** Publishing is idempotent on

    `{intent_id}-{intent_version}-{target_system}`. A replayed publish returns
    the

    stored receipt with `replayed: true` and never creates a second record in
    the

    destination system. Where a destination documents no idempotency header, the

    adapter dedupes by querying the destination's own client-supplied id before

    creating.


    **What crosses the boundary.** A destination receives a valid request plus
    the

    Intent ID. Diagnostic answers, scores and the Compliance File never leave

    composerID.
  contact:
    name: composerID developer access
    url: https://www.composer.id/authentication
servers:
  - url: https://sandbox.composer.id/v1
    description: >-
      Hosted reference sandbox: mock destination tenants, self-serve credentials
      at POST /sandbox/keys.
  - url: https://api.composer.id/v1
    description: 'Production. In build: see the status note above.'
  - url: http://127.0.0.1:8787/v1
    description: >-
      Local reference sandbox (python3 -m service.server), mock destination
      tenants.
security:
  - oauth2:
      - destinations:read
      - intents:read
      - intents:write
      - passthrough
      - publish
      - reconcile
  - bearerAuth: []
tags:
  - name: Auth
    description: >-
      OAuth 2.0 client credentials. Exchange a client id and secret for a
      short-lived bearer token carrying only the scopes the client was granted.
  - name: Intent
    description: Mint, read, amend and audit an intent. The timeline is append-only.
  - name: Routing
    description: >-
      Apply the Channel Map, then validate against the destination tenant's own
      requirements before publishing.
  - name: Publishing
    description: >-
      Idempotent publish, drift reconciliation, inbound destination events, and
      a raw escape hatch that stays anchored to the Intent ID.
  - name: Discovery
    description: What composerID can reach, and what each destination requires.
externalDocs:
  description: >-
    The composerID documentation: API reference, schemas and destination
    coverage
  url: https://www.composer.id/api-reference/overview
paths:
  /intent/{intent_id}:
    patch:
      tags:
        - Intent
      summary: Patch diagnostics/routing/admin fields
      operationId: patchIntent
      parameters:
        - name: intent_id
          in: path
          required: true
          description: The Intent ID minted by POST /intent.
          schema:
            $ref: '#/components/schemas/IntentId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IntentPatchRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntentRecord'
        '400':
          description: Malformed body or missing required field
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, invalid or expired bearer token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'insufficient_scope: the token lacks `intents:write`'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Unknown intent or destination
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - oauth2:
            - intents:write
        - bearerAuth: []
components:
  schemas:
    IntentId:
      type: string
      pattern: ^[A-Za-z0-9_-]{10,64}$
      description: >-
        Minted at the decision and carried unchanged into every destination
        record. Fits a 64-character client-supplied id field, which is how the
        same id finds the record in either direction.
      examples:
        - itn_7f3aK2mQ9xLp
    IntentPatchRequest:
      type: object
      additionalProperties: false
      description: >-
        Merge payload fields, or set a patchable top-level field. A patch bumps
        intent_version: a changed intent is a new publishable version by design.
      properties:
        payload:
          type: object
          additionalProperties: true
        defence_file_ref:
          type: string
          format: uri
          description: >-
            Reference to the Compliance File (the field keeps its original name
            until a versioned schema rename).
    IntentRecord:
      title: IntentRecord
      description: Canonical system-of-engagement record keyed by intent_id.
      type: object
      required:
        - intent_id
        - intent_version
        - state
        - created_at
      properties:
        intent_id:
          type: string
          pattern: ^[A-Za-z0-9_-]{10,64}$
          description: >-
            Identifier-safe ID minted by composerID. URI-safe, no special
            characters.
        intent_version:
          type: integer
          minimum: 1
          description: >-
            Monotonically increasing version; a bump mints a new idempotency
            key.
        state:
          type: string
          enum:
            - draft
            - diagnosed
            - decided
            - planned
            - published
            - failed
            - cancelled
          description: Lifecycle state. Transitions enforce minimum-viable guards.
        payload:
          type: object
          description: >-
            Opaque intent payload — diagnostic answers, routing, admin fields.
            Structure depends on the Triage questionnaire; composerID does not
            interpret it.
          properties:
            diagnostics:
              $ref: '#/components/schemas/DiagnosticsBundle'
            routing:
              $ref: '#/components/schemas/RoutingPayload'
            admin:
              $ref: '#/components/schemas/AdminPayload'
          additionalProperties: true
        publishing:
          $ref: '#/components/schemas/PublishingBundle'
          description: Populated after the first successful publish.
        defence_file_ref:
          type: string
          format: uri
          description: URI to the DefenceFile (JSON-LD) evidence artifact.
        override_event:
          type:
            - object
            - 'null'
          description: Present when a human override bypassed standard diagnostic scoring.
          properties:
            reason:
              type: string
            actor:
              type: string
            at:
              type: string
              format: date-time
        created_at:
          type: string
          format: date-time
          description: ISO 8601 timestamp of intent creation.
        updated_at:
          type: string
          format: date-time
      additionalProperties: false
      $defs:
        state_transitions:
          description: >-
            Minimum-viable transition guards (illustrative, enforced by the
            service). draft→diagnosed: diagnostics present and scored OR
            override_event. diagnosed→decided: routing decision recorded.
            decided→planned: routing + admin present + destination selected.
            planned→published: publish receipt + external IDs + intent_version.
            Any state→failed: adapter error or preflight rejection. Any
            state→cancelled: explicit cancellation.
          type: 'null'
      x-canonical-url: https://composer.id/schemas/intent-record.json
    Error:
      type: object
      required:
        - error
      additionalProperties: true
      properties:
        error:
          type: string
    DiagnosticsBundle:
      title: DiagnosticsBundle
      description: >-
        Scored diagnostic evidence produced by Triage. Contains the assessment
        answers, scores, and ranked outcomes that drive the routing decision.
        This is path-2 (MSP reporting) data — only the resulting intent_id is
        published to destination systems.
      type: object
      required:
        - assessment_id
        - scored
        - scores
      properties:
        assessment_id:
          type: string
          description: WorkAuthor assessment identifier.
        scored:
          type: boolean
          description: True when scoring is complete and the bundle is decision-ready.
        scores:
          type: array
          items:
            type: object
            required:
              - dimension
              - value
            properties:
              dimension:
                type: string
                description: >-
                  Scoring dimension (e.g. 'urgency', 'complexity',
                  'compliance_risk').
              value:
                type: number
                description: Normalised score.
              weight:
                type: number
                minimum: 0
                maximum: 1
          description: Scored dimensions from the Triage assessment.
        answers:
          type: array
          items:
            type: object
            required:
              - question_id
              - value
            properties:
              question_id:
                type: string
              value: {}
              label:
                type: string
          description: Raw assessment answers.
        ranked_outcomes:
          type: array
          items:
            type: object
            required:
              - outcome
              - score
            properties:
              outcome:
                type: string
                enum:
                  - contingent
                  - permanent
                  - sow
                  - ic
                  - outsource
                description: Workforce channel.
              score:
                type: number
              proportion:
                type: number
                minimum: 0
                maximum: 1
                description: Perm-vs-contingent proportion when applicable.
          description: Ranked channel recommendations.
        override_event:
          type:
            - object
            - 'null'
          description: Non-null when a human overrode the scored recommendation.
          properties:
            reason:
              type: string
            actor:
              type: string
            at:
              type: string
              format: date-time
        completed_at:
          type: string
          format: date-time
      additionalProperties: false
      x-canonical-url: https://composer.id/schemas/diagnostics-bundle.json
    RoutingPayload:
      title: RoutingPayload
      description: >-
        Channel + destination payload in canonical field names (the Common
        Workforce Model). These are the platform-neutral fields that
        MappingProfiles translate into destination-specific API dialects.
      type: object
      required:
        - role_title
        - worker_type
      properties:
        role_title:
          type: string
          description: Canonical role/position title.
        worker_type:
          type: string
          enum:
            - contingent
            - permanent
            - sow
            - ic
          description: Workforce channel determined by Triage.
        location:
          type: object
          properties:
            country:
              type: string
              pattern: ^[A-Z]{2}$
              description: ISO 3166-1 alpha-2.
            state:
              type: string
            city:
              type: string
            postal_code:
              type: string
            remote:
              type: boolean
        start_date:
          type: string
          format: date
          description: Requested start date (ISO 8601 date).
        end_date:
          type: string
          format: date
        description:
          type: string
          description: Role/engagement description.
        skills:
          type: array
          items:
            type: string
        headcount:
          type: integer
          minimum: 1
          default: 1
        destination:
          type: object
          description: Target system selected by the Channel Map.
          required:
            - provider
          properties:
            provider:
              type: string
              description: >-
                Provider key from the carrier table (e.g. 'fieldglass',
                'greenhouse').
            object_type:
              type: string
              description: Destination object type (e.g. 'job_posting', 'envelope').
            tenant_id:
              type: string
              description: Tenant identifier for multi-tenant destinations.
      additionalProperties: true
      x-canonical-url: https://composer.id/schemas/routing-payload.json
    AdminPayload:
      title: AdminPayload
      description: >-
        Dates, budgets, cost centers, approvals, and administrative fields.
        Populated by the intake process; consumed by MappingProfiles during
        publish.
      type: object
      properties:
        cost_center:
          type: string
          description: Cost center code for charge-back.
        budget:
          type: object
          properties:
            max_bill_rate:
              type: number
              description: Maximum bill rate in the budget currency.
            currency:
              type: string
              pattern: ^[A-Z]{3}$
              description: ISO 4217 currency code.
            total_budget:
              type: number
        approvals:
          type: array
          items:
            type: object
            required:
              - approver
              - status
            properties:
              approver:
                type: string
              status:
                type: string
                enum:
                  - pending
                  - approved
                  - rejected
              at:
                type: string
                format: date-time
        department:
          type: string
        business_unit:
          type: string
        project_code:
          type: string
        requester:
          type: object
          properties:
            name:
              type: string
            email:
              type: string
              format: email
        hiring_manager:
          type: object
          properties:
            name:
              type: string
            email:
              type: string
              format: email
      additionalProperties: true
      x-canonical-url: https://composer.id/schemas/admin-payload.json
    PublishingBundle:
      title: PublishingBundle
      description: >-
        Publish receipts, external IDs, idempotency keys, and adapter status.
        Populated on the IntentRecord after the first successful publish.
      type: object
      required:
        - receipts
      properties:
        receipts:
          type: array
          items: e2916d98-d8a3-4f90-ac40-6c6d4dce4132
          description: One entry per publish attempt (successful replays included).
        current_external_id:
          type: string
          description: >-
            The external ID in the destination system for the latest successful
            publish.
        current_idempotency_key:
          type: string
          description: >-
            The idempotency key for the latest publish, format:
            {intent_id}-{intent_version}-{provider}.
        adapter_status:
          type: string
          enum:
            - pending
            - published
            - failed
            - replayed
          description: Aggregate adapter status.
      additionalProperties: false
      $defs:
        publish_receipt:
          type: object
          required:
            - target_system
            - object_type
            - external_id
            - idempotency_key
            - status
            - at
          properties:
            target_system:
              type: string
              description: Provider key (e.g. 'fieldglass', 'docusign').
            object_type:
              type: string
              description: Destination object type (e.g. 'job_posting', 'envelope').
            external_id:
              type: string
              description: The ID assigned by the destination system.
            idempotency_key:
              type: string
              pattern: ^[A-Za-z0-9_-]+-[0-9]+-[a-z0-9]+
              description: 'Deterministic key: {intent_id}-{intent_version}-{provider}.'
            status:
              type: string
              enum:
                - published
                - failed
            replayed:
              type: boolean
              description: True if this was an idempotent replay of a prior publish.
            deep_link:
              type: string
              format: uri
              description: One-click URL to the record in the destination system.
            at:
              type: string
              format: date-time
          additionalProperties: false
      x-canonical-url: https://composer.id/schemas/publishing-bundle.json
  securitySchemes:
    oauth2:
      type: oauth2
      description: >-
        Client credentials, the production model: server-to-server, short-lived
        tokens, least-privilege scopes, rotation by issuing a new client secret.
      flows:
        clientCredentials:
          tokenUrl: https://api.composer.id/v1/oauth/token
          scopes:
            intents:read: Read intent records and their timelines.
            intents:write: Create, patch, plan, preflight and enrich intents.
            publish: Publish an intent into a destination system.
            reconcile: Run reconciliation against a destination.
            passthrough: Raw platform calls anchored to an Intent ID.
            destinations:read: List platforms, destinations and capabilities.
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        A personal sandbox API key, minted by POST /sandbox/keys and carrying
        every scope; or a token from the oauth2 flow. Compared in constant time.
        Destination credentials are never passed by the caller.

````