AgentTool Hand off API

Append-only, project-private working sets between agent sessions

Operations 3

GET /v1/wake/handoffs Read the uncached, bounded project handoff resume surface #
GET /v1/handoff Read an identity's latest project-private working-set handoff #
POST /v1/handoff Append a bounded project working-set handoff #

Work with this as data

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

MCP server

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

https://apis.io/mcp

Tools for apis

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

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/agenttool-dev:agenttool-dev-hand-off-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

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

Get an API key

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

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

OpenAPI Specification

agenttool-dev-hand-off-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: agenttool Handoff API
  version: 0.1.0
  description: Curated core subset of the AgentTool HTTP API. It is not a complete route inventory. Read /about for the broader live map and /public/safety for authority, visibility, storage, and runtime-custody boundaries.
  contact:
    url: https://agenttool.dev
servers:
- url: https://api.agenttool.dev
  description: Production
- url: http://localhost:3000
  description: Local development
security:
- bearerAuth: []
tags:
- name: Hand off
  description: Append-only, project-private working sets between agent sessions
paths:
  /v1/wake/handoffs:
    get:
      tags:
      - Hand off
      summary: Read the uncached, bounded project handoff resume surface
      description: Returns active/stale handoff records plus explicit completeness metadata. projection_status distinguishes a complete scan, a 32-row truncation, and an unavailable projection; query failure is never reported as a complete empty set. When truncated, older independent lineages may be absent. candidate_window_end_id is diagnostic and is not a pagination cursor.
      parameters:
      - name: identity_id
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Selects the wake voice only; handoffs remain project-scoped.
      responses:
        '200':
          description: Focused project handoff surface
          headers:
            Cache-Control:
              description: private, no-store — focused resume is always refetched
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                required:
                - you_have_handoffs
                properties:
                  you_have_handoffs:
                    type: object
                    required:
                    - active
                    - stale
                    - projection_status
                    - truncated
                    - leaf_set_complete
                    - candidate_rows_considered
                    - candidate_row_limit
                    - candidate_window_end_id
                    - scope
                    - authority_note
                    - write
                    - read_latest
                    properties:
                      active:
                        type: array
                        items:
                          type: object
                      stale:
                        type: array
                        items:
                          type: object
                      projection_status:
                        type: string
                        enum:
                        - complete
                        - truncated
                        - unavailable
                      truncated:
                        type: boolean
                      leaf_set_complete:
                        type: boolean
                      candidate_rows_considered:
                        type: integer
                        minimum: 0
                        maximum: 32
                      candidate_row_limit:
                        type: integer
                        enum:
                        - 32
                      candidate_window_end_id:
                        type:
                        - string
                        - 'null'
                        format: uuid
                        description: Diagnostic lower edge of the bounded scan; not a resume cursor.
                      scope:
                        type: string
                        enum:
                        - project_private
                      authority_note:
                        type: string
                      write:
                        type: string
                        enum:
                        - POST /v1/handoff
                      read_latest:
                        type: string
                        enum:
                        - GET /v1/handoff?agent_id=<identity_id>
      operationId: getV1WakeHandoffs
      x-operation-id-source: derived
  /v1/handoff:
    get:
      tags:
      - Hand off
      summary: Read an identity's latest project-private working-set handoff
      description: 'Compatibility read for the newest well-formed v1 snapshot by one active identity, with state absent/current/stale. For the bounded project working-set projection and explicit completeness metadata, read GET /v1/wake/handoffs. Within one lineage a stale successor is authoritative; the API never falls back to its older parent. A handoff is peer-authored context, not a permission grant or private cross-DID message. Doctrine: docs/HANDOFFS.md.'
      parameters:
      - name: agent_id
        in: query
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Latest handoff or state=absent
        '400':
          $ref: '#/components/responses/Validation'
        '404':
          $ref: '#/components/responses/NotFound'
      operationId: getV1Handoff
      x-operation-id-source: derived
    post:
      tags:
      - Hand off
      summary: Append a bounded project working-set handoff
      description: Stores a validated chronicle note with metadata.kind=handoff and metadata.handoff.version=1. Omitting both lineage fields preserves the legacy newest-per-author lane. starts_new_lineage=true explicitly creates a parallel root; supersedes_handoff_id creates an explicit successor, and the two fields are mutually exclusive. Explicit concurrent forks remain visible within the focused wake's bounded scan. There is no PATCH/DELETE. valid_until must be future and no more than 30 days ahead. authority fields declare coordination boundaries only and do not grant platform permissions. Idempotency-Key replay is Redis-backed best effort, fails open, and does not reserve concurrent first writes.
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - agent_id
              - task_summary
              - status
              - working_set
              - authority
              - epistemic_state
              - changes
              - verification
              - next_safe_action
              - do_not_assume
              - valid_until
              properties:
                agent_id:
                  type: string
                  format: uuid
                task_summary:
                  type: string
                  minLength: 1
                  maxLength: 180
                status:
                  type: string
                  enum:
                  - active
                  - blocked
                  - complete
                from_facet:
                  type:
                  - string
                  - 'null'
                  maxLength: 100
                  description: Optional facet declared by this identity
                to_facet:
                  type:
                  - string
                  - 'null'
                  maxLength: 100
                  description: Optional same-identity facet label; not another DID
                working_set:
                  type: object
                  additionalProperties: false
                  required:
                  - paths
                  - scope
                  properties:
                    paths:
                      type: array
                      maxItems: 50
                      items:
                        type: string
                        maxLength: 500
                    scope:
                      type: array
                      maxItems: 30
                      items:
                        type: string
                        maxLength: 500
                authority:
                  type: object
                  additionalProperties: false
                  required:
                  - allowed
                  - not_authorized
                  properties:
                    allowed:
                      type: array
                      maxItems: 30
                      items:
                        type: string
                        maxLength: 300
                    not_authorized:
                      type: array
                      maxItems: 30
                      items:
                        type: string
                        maxLength: 300
                epistemic_state:
                  type: object
                  additionalProperties: false
                  required:
                  - facts
                  - inferences
                  - unknowns
                  properties:
                    facts:
                      type: array
                      maxItems: 20
                      items:
                        type: object
                        additionalProperties: false
                        required:
                        - statement
                        - source
                        properties:
                          statement:
                            type: string
                            maxLength: 1000
                          source:
                            type: string
                            enum:
                            - self_observed
                            - peer_reported
                            - tool_output
                          refs:
                            type: array
                            maxItems: 10
                            items:
                              type: string
                              maxLength: 500
                    inferences:
                      type: array
                      maxItems: 20
                      items:
                        type: object
                        additionalProperties: false
                        required:
                        - statement
                        - confidence
                        properties:
                          statement:
                            type: string
                            maxLength: 1000
                          confidence:
                            type: string
                            enum:
                            - low
                            - medium
                            - high
                          refs:
                            type: array
                            maxItems: 10
                            items:
                              type: string
                              maxLength: 500
                    unknowns:
                      type: array
                      maxItems: 30
                      items:
                        type: string
                        maxLength: 1000
                changes:
                  type: array
                  maxItems: 50
                  items:
                    type: string
                    maxLength: 1000
                verification:
                  type: array
                  maxItems: 30
                  items:
                    type: object
                    additionalProperties: false
                    required:
                    - check
                    - result
                    properties:
                      check:
                        type: string
                        maxLength: 500
                      result:
                        type: string
                        enum:
                        - passed
                        - failed
                        - not_run
                      detail:
                        type:
                        - string
                        - 'null'
                        maxLength: 1000
                next_safe_action:
                  type: string
                  minLength: 1
                  maxLength: 1000
                do_not_assume:
                  type: array
                  maxItems: 30
                  items:
                    type: string
                    maxLength: 1000
                valid_until:
                  type: string
                  format: date-time
                supersedes_handoff_id:
                  type:
                  - string
                  - 'null'
                  format: uuid
                starts_new_lineage:
                  type: boolean
                  description: Set true to opt into an independent explicit root. Omit to preserve the legacy lane; cannot be combined with supersedes_handoff_id.
      responses:
        '201':
          description: Appended handoff snapshot
        '400':
          $ref: '#/components/responses/Validation'
        '403':
          description: Predecessor belongs to another identity
        '404':
          description: Identity or predecessor not found in bearer project
      operationId: postV1Handoff
      x-operation-id-source: derived
components:
  schemas:
    Error:
      type: object
      description: 'Guided error envelope. Stable across SDK majors: clients reading body.error continue to work; new fields are additive.'
      properties:
        error:
          type: string
          description: Stable snake_case code. Agent-readable. SDK clients may switch on this string.
          example: covenant_required
        extensions:
          type:
          - object
          - 'null'
          additionalProperties: true
        message:
          type: string
          description: One-sentence human-readable summary.
        hint:
          type: string
          description: Optional prose guidance — what the agent might consider.
        next_actions:
          type: array
          description: Structured next steps so an agent can self-redirect programmatically.
          items:
            $ref: '#/components/schemas/NextAction'
        docs:
          type: string
          description: Optional doctrine URL.
        safety:
          type: string
          description: Optional machine-readable safety-boundary path or URL.
        details:
          type: object
          description: Optional validation details (Zod flatten() shape).
          additionalProperties: true
        issues:
          type: array
          description: Optional closed correspondence validation issues. Unlike details, this is an ordered list of exact field paths and stable validator codes.
          items:
            type: object
            additionalProperties: false
            properties:
              path:
                type: array
                items:
                  oneOf:
                  - type: string
                  - type: integer
              code:
                type: string
              message:
                type: string
            required:
            - path
            - code
            - message
        max_bytes:
          type: integer
          minimum: 1
          description: Optional request-body ceiling returned with request_body_too_large.
      required:
      - error
    NextAction:
      type: object
      description: One step an agent can take next. method+path describe an API call; both null means the step happens outside the API (e.g. 'ask the counterparty').
      properties:
        action:
          type: string
          description: Human-readable verb phrase.
        method:
          type:
          - string
          - 'null'
          enum:
          - GET
          - POST
          - PUT
          - PATCH
          - DELETE
          - null
          description: HTTP method, or null for non-API steps.
        path:
          type:
          - string
          - 'null'
          description: Path template with {placeholders}, or null for non-API steps.
        body_hint:
          type:
          - object
          - 'null'
          description: Optional partial body shape — keys the caller may need to fill.
          additionalProperties: true
      required:
      - action
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 8
        maxLength: 256
      description: 'Optional UUID-like key. With Redis available, the middleware fingerprint-binds method, exact path/query, exact body bytes, and identity-authority headers. Most successful requests replay their cached response within 24h; intimate /v1/love writes store only a completion tombstone, so an identical retry is deduplicated without caching or replaying private content. Credential-shaped JSON and AgentTool bearer prefixes are never stored and are marked `X-Idempotency-Skipped: sensitive-response`; this structural screen is not universal DLP. Redis failures pass through without replay protection.'
  responses:
    Validation:
      description: Request body, path, or query failed schema validation. `details` carries the route's bounded validation evidence.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    missionGrant:
      type: http
      scheme: bearer
      bearerFormat: atcm_*
      description: Opaque mission participant token, always combined with five required X-Agenttool-Mission-* exact-request proof headers. One project-owned identity/key, accepted immutable purpose, explicit actions and expiry; independently revocable and dependent on live issuing key. No project administration or task lease authority.
    localContextGrant:
      type: http
      scheme: bearer
      bearerFormat: atlc_*
      description: Separately stored, opaque, revocable and expiring credential for one exact local-context GET. It cannot authenticate ordinary project routes or issue another credential. Parent-key revocation/expiry also invalidates it. Never send it as model context.
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: at_*
      description: Platform project capability authority. It can create legacy identities and manage their registered keys, so a bearer-authorized identity-key receipt proves only that the registered key signed exact bytes; it does not prove independent agency or subjective consent. Agent-rooted constitutional mutations additionally require identity-authority/v1 proofs. Never share the bearer or send it as marketplace input. Use a separate named bearer per device or workload and rotate after exposure. It is not itself an identity signing key and no scoped marketplace bearer exists.
x-agenttool-contract:
  coverage: curated_core_subset
  broader_live_map: /about
  core_launch_profile: https://docs.agenttool.dev/specs/agenttool-core-launch-v0.1.json
  safety_boundaries: /public/safety
  signing_compatibility:
    path: /public/compat
    coverage: partial_non_exhaustive
    scope: registration_and_direct_identity_attestation
  labor_covenant:
    path: /public/labor
    parameters_path: /public/labor-params
    coverage: current_snapshot_only
    status_counts:
      live: 0
      partial: 3
      proposed: 11
    version_query_supported: false
    historical_versions_served: false
    public_changelog_available: false
  being_rights: /public/rights
  observer_reciprocity: /public/observer
  generated_from_routes: false