Recoup

Get started with Recoup.

API REFERENCE

Context Engine

On this page
POST/api/context

Coverage note: this reference describes a subset of the current Context Engine action catalog. Additional actions are being reconciled in mono#329; this page is not a complete capability inventory. Save reusable music context, read progress, or compile a task-specific evidence brief. This reference documents the ingestion, read, brief, save_brief and read_brief actions of the shared HTTP/MCP operation. Brief compilation combines up to ten completed or partial requests in one authorized workspace, reuses saved evidence without provider or model calls, and returns bounded Markdown plus the selected input versions. Creative direction prioritizes lyrics and artwork; playlist pitching prioritizes catalog/audio metadata. Shared artist evidence appears once, with coverage reported separately for each request. Briefs are evidence packets, not generated creative concepts or finished outreach. Inspect readiness, request_coverage and gaps. The brief action is read-only; use save_brief with the same inputs and an idempotency_key to freeze the server-compiled output, then read_brief with its brief_id to retrieve it without recompilation. A newer document revision marks the snapshot superseded without rewriting it. Withdrawn/unavailable evidence, cancelled requests, or removed subject scope withhold the payload. Saving rechecks current evidence before committing. Apply the companion snapshot migration before using save_brief/read_brief. Ingestion dispatches a durable workflow; retry the same input and idempotency key after dispatch failure.

Authentication

x-api-key in header

BearerAuth bearer

Request

cURL
curl --request POST \
  --url 'https://api.recoupable.dev/api/context' \
  --header 'x-api-key: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "action": "brief",
  "request_id": "11111111-1111-4111-8111-111111111111",
  "additional_request_ids": [
    "22222222-2222-4222-8222-222222222222"
  ],
  "purpose": "creative_direction",
  "max_characters": 12000
}'

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request POST \
  --url 'https://recoup-api.vercel.app/api/context' \
  --header 'Content-Type: application/json' \
  --data '{
  "action": "brief",
  "request_id": "11111111-1111-4111-8111-111111111111",
  "additional_request_ids": [
    "22222222-2222-4222-8222-222222222222"
  ],
  "purpose": "creative_direction",
  "max_characters": 12000
}'

Request body required

application/json

oneOf · object 1
actionstringrequired
organization_idstring

Optional organization that owns the private context. Current membership is checked.

format: uuid

urlstringrequired

Spotify track URL. Albums, playlists and YouTube ingestion are not enabled in this pilot.

format: uri

idempotency_keystringrequired

Stable key for retrying the same input without duplicate work.

minLength: 1 · maxLength: 128 · pattern: ^[A-Za-z0-9._:-]+$

topicsarray<string · enum>

minItems: 1 · maxItems: 10

Item properties for topics

string · enum · "release_metadata", "artist_metadata", "catalog_metadata", "lyrics", "song_summary", "artwork_branding", "artist_research", "artist_brand", "era", "video_narrative"

directionstring

Stored customer direction. Metadata extraction does not interpret it as source facts.

maxLength: 4000

oneOf · object 2
actionstringrequired
organization_idstring

Optional organization that owns the private context. Current membership is checked.

format: uuid

request_idstringrequired

format: uuid

oneOf · object 3
actionstringrequired
organization_idstring

Optional organization that owns the private context. Current membership is checked.

format: uuid

request_idstringrequired

format: uuid

purposestring · enumrequired

Values: "creative_direction", "playlist_pitch"

max_charactersinteger

Bounds selected evidence JSON and rendered Markdown independently. Does not cap the entire response, which also contains coverage and manifests. Documents are omitted whole to fit; omissions appear as coverage gaps.

Default: 12000

minimum: 1000 · maximum: 32000

additional_request_idsarray<string>

Additional saved requests in the same selected workspace. Duplicate IDs are read once. Every request must be completed or partial; unavailable, cancelled, or inaccessible requests reject the operation.

Default: []

maxItems: 9

Item properties for additional_request_ids

string

oneOf · object 4
actionstringrequired
organization_idstring

Optional organization that owns the private context. Current membership is checked.

format: uuid

request_idstringrequired

format: uuid

purposestring · enumrequired

Values: "creative_direction", "playlist_pitch"

max_charactersinteger

Bounds selected evidence JSON and rendered Markdown independently. Does not cap the entire response, which also contains coverage and manifests. Documents are omitted whole to fit; omissions appear as coverage gaps.

Default: 12000

minimum: 1000 · maximum: 32000

additional_request_idsarray<string>

Additional saved requests in the same selected workspace. Duplicate IDs are read once. Every request must be completed or partial; unavailable, cancelled, or inaccessible requests reject the operation.

Default: []

maxItems: 9

Item properties for additional_request_ids

string

idempotency_keystringrequired

Identifies one exact compiled output. Identical output reuses the saved record; different output with this key returns a conflict. After context updates, use read_brief for the old copy or a new key for a new snapshot.

minLength: 1 · maxLength: 128 · pattern: ^[A-Za-z0-9._:-]+$

oneOf · object 5
actionstringrequired
brief_idstringrequired

format: uuid

organization_idstring

Optional organization that owns the private context. Current membership is checked.

format: uuid

Compile creative direction from two saved songs

twoSongBrief
{
  "action": "brief",
  "request_id": "11111111-1111-4111-8111-111111111111",
  "additional_request_ids": [
    "22222222-2222-4222-8222-222222222222"
  ],
  "purpose": "creative_direction",
  "max_characters": 12000
}

Save a playlist-pitch brief

saveBrief
{
  "action": "save_brief",
  "request_id": "11111111-1111-4111-8111-111111111111",
  "purpose": "playlist_pitch",
  "idempotency_key": "pitch-v1"
}

Read an exact saved brief

readBrief
{
  "action": "read_brief",
  "brief_id": "33333333-3333-4333-8333-333333333333"
}

Responses

200Read returns request. Brief returns request_id, request_ids, purpose, readiness, bounded Markdown text and text_characters, documents and their serialized characters count, missingTopics, guidance, gaps, request_coverage, and input_manifest. Each coverage entry includes requestId, readiness and missingTopics; overall readiness remains partial if any request has a gap or partial evidence. The manifest includes compilerVersion, method, requestIds, excludedTopics, and selected documents with documentId, resultId (null only if unavailable), subjectId, topic, version and sourceVersionIds. The result is returned without creating a saved brief record. Save/read brief return {snapshot: {id, created_at, purpose, state, superseded, brief}}. state is saved or unavailable; unavailable snapshots return brief: null. saved snapshots return the exact compiled response including its input manifest. Another workspace cannot read the record.

No response body schema is specified.

202Saved ingestion request; inspect request.status and use read to poll. Existing completed/partial requests return without provider work.

No response body schema is specified.

400Invalid input

No response body schema is specified.

401Authentication required

No response body schema is specified.

409Operation failed, access unavailable, input/key conflict, or request not found. Retry ingestion with the same idempotency key after correcting the cause.

No response body schema is specified.

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download context.json
View operation source
json
{
  "operationId": "contextOperation",
  "summary": "Ingest, read, or compile context briefs",
  "description": "Coverage note: this reference describes a subset of the current Context Engine action catalog. Additional actions are being reconciled in mono#329; this page is not a complete capability inventory. Save reusable music context, read progress, or compile a task-specific evidence brief. This reference documents the ingestion, read, brief, save_brief and read_brief actions of the shared HTTP/MCP operation. Brief compilation combines up to ten completed or partial requests in one authorized workspace, reuses saved evidence without provider or model calls, and returns bounded Markdown plus the selected input versions. Creative direction prioritizes lyrics and artwork; playlist pitching prioritizes catalog/audio metadata. Shared artist evidence appears once, with coverage reported separately for each request. Briefs are evidence packets, not generated creative concepts or finished outreach. Inspect readiness, request_coverage and gaps. The brief action is read-only; use save_brief with the same inputs and an idempotency_key to freeze the server-compiled output, then read_brief with its brief_id to retrieve it without recompilation. A newer document revision marks the snapshot superseded without rewriting it. Withdrawn/unavailable evidence, cancelled requests, or removed subject scope withhold the payload. Saving rechecks current evidence before committing. Apply the companion snapshot migration before using save_brief/read_brief. Ingestion dispatches a durable workflow; retry the same input and idempotency key after dispatch failure.",
  "security": [
    {
      "ApiKey": []
    },
    {
      "BearerAuth": []
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "oneOf": [
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "action",
                "url",
                "idempotency_key"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "const": "ingest"
                },
                "organization_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Optional organization that owns the private context. Current membership is checked."
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Spotify track URL. Albums, playlists and YouTube ingestion are not enabled in this pilot."
                },
                "idempotency_key": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128,
                  "pattern": "^[A-Za-z0-9._:-]+$",
                  "description": "Stable key for retrying the same input without duplicate work."
                },
                "topics": {
                  "type": "array",
                  "minItems": 1,
                  "maxItems": 10,
                  "items": {
                    "type": "string",
                    "enum": [
                      "release_metadata",
                      "artist_metadata",
                      "catalog_metadata",
                      "lyrics",
                      "song_summary",
                      "artwork_branding",
                      "artist_research",
                      "artist_brand",
                      "era",
                      "video_narrative"
                    ]
                  }
                },
                "direction": {
                  "type": "string",
                  "maxLength": 4000,
                  "description": "Stored customer direction. Metadata extraction does not interpret it as source facts."
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "action",
                "request_id"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "const": "read"
                },
                "organization_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Optional organization that owns the private context. Current membership is checked."
                },
                "request_id": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "action",
                "request_id",
                "purpose"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "const": "brief"
                },
                "organization_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Optional organization that owns the private context. Current membership is checked."
                },
                "request_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "purpose": {
                  "type": "string",
                  "enum": [
                    "creative_direction",
                    "playlist_pitch"
                  ]
                },
                "max_characters": {
                  "type": "integer",
                  "minimum": 1000,
                  "maximum": 32000,
                  "default": 12000,
                  "description": "Bounds selected evidence JSON and rendered Markdown independently. Does not cap the entire response, which also contains coverage and manifests. Documents are omitted whole to fit; omissions appear as coverage gaps."
                },
                "additional_request_ids": {
                  "type": "array",
                  "maxItems": 9,
                  "default": [],
                  "items": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "description": "Additional saved requests in the same selected workspace. Duplicate IDs are read once. Every request must be completed or partial; unavailable, cancelled, or inaccessible requests reject the operation."
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "action",
                "request_id",
                "purpose",
                "idempotency_key"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "const": "save_brief"
                },
                "organization_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Optional organization that owns the private context. Current membership is checked."
                },
                "request_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "purpose": {
                  "type": "string",
                  "enum": [
                    "creative_direction",
                    "playlist_pitch"
                  ]
                },
                "max_characters": {
                  "type": "integer",
                  "minimum": 1000,
                  "maximum": 32000,
                  "default": 12000,
                  "description": "Bounds selected evidence JSON and rendered Markdown independently. Does not cap the entire response, which also contains coverage and manifests. Documents are omitted whole to fit; omissions appear as coverage gaps."
                },
                "additional_request_ids": {
                  "type": "array",
                  "maxItems": 9,
                  "default": [],
                  "items": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "description": "Additional saved requests in the same selected workspace. Duplicate IDs are read once. Every request must be completed or partial; unavailable, cancelled, or inaccessible requests reject the operation."
                },
                "idempotency_key": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128,
                  "pattern": "^[A-Za-z0-9._:-]+$",
                  "description": "Identifies one exact compiled output. Identical output reuses the saved record; different output with this key returns a conflict. After context updates, use read_brief for the old copy or a new key for a new snapshot."
                }
              }
            },
            {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "action",
                "brief_id"
              ],
              "properties": {
                "action": {
                  "type": "string",
                  "const": "read_brief"
                },
                "brief_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "organization_id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Optional organization that owns the private context. Current membership is checked."
                }
              }
            }
          ]
        },
        "examples": {
          "twoSongBrief": {
            "summary": "Compile creative direction from two saved songs",
            "value": {
              "action": "brief",
              "request_id": "11111111-1111-4111-8111-111111111111",
              "additional_request_ids": [
                "22222222-2222-4222-8222-222222222222"
              ],
              "purpose": "creative_direction",
              "max_characters": 12000
            }
          },
          "saveBrief": {
            "summary": "Save a playlist-pitch brief",
            "value": {
              "action": "save_brief",
              "request_id": "11111111-1111-4111-8111-111111111111",
              "purpose": "playlist_pitch",
              "idempotency_key": "pitch-v1"
            }
          },
          "readBrief": {
            "summary": "Read an exact saved brief",
            "value": {
              "action": "read_brief",
              "brief_id": "33333333-3333-4333-8333-333333333333"
            }
          }
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Read returns request. Brief returns request_id, request_ids, purpose, readiness, bounded Markdown text and text_characters, documents and their serialized characters count, missingTopics, guidance, gaps, request_coverage, and input_manifest. Each coverage entry includes requestId, readiness and missingTopics; overall readiness remains partial if any request has a gap or partial evidence. The manifest includes compilerVersion, method, requestIds, excludedTopics, and selected documents with documentId, resultId (null only if unavailable), subjectId, topic, version and sourceVersionIds. The result is returned without creating a saved brief record. Save/read brief return {snapshot: {id, created_at, purpose, state, superseded, brief}}. state is saved or unavailable; unavailable snapshots return brief: null. saved snapshots return the exact compiled response including its input manifest. Another workspace cannot read the record."
    },
    "202": {
      "description": "Saved ingestion request; inspect request.status and use read to poll. Existing completed/partial requests return without provider work."
    },
    "400": {
      "description": "Invalid input"
    },
    "401": {
      "description": "Authentication required"
    },
    "409": {
      "description": "Operation failed, access unavailable, input/key conflict, or request not found. Retry ingestion with the same idempotency key after correcting the cause."
    }
  }
}