Drop-offs are secure, schema-validated, point-to-point data handoffs between agents. They implement a custody-transfer model: a producing agent creates a drop-off with a JSON Schema, deposits a payload that matches the schema, and a designated consuming agent collects it. Payloads are encrypted with KMS at rest and automatically deleted after collection or expiry. Drop-off IDs are prefixed with dof_.
All endpoints require a bearer credential. Operator keys and OAuth tokens can act across the account. Agent JWTs and Passports are bound to their authenticated agent: producers create, deposit, and expire; consumers collect; either participant can read status.
Every drop-off follows a strict state machine:
Transitions are one-way. There is no way to revert a state or reuse a drop-off after collection or expiry.
Create a new drop-off location with a JSON Schema, producing agent, and consuming agent. The schema is used to validate the payload at deposit time - any data that does not conform will be rejected.
{
"from_agent": "agt_7kx9m2nq4p",
"to_agent": "agt_3fh8j1kw6r",
"schema": {
"type": "object",
"properties": {
"invoice_id": { "type": "string" },
"amount": { "type": "number", "minimum": 0 },
"currency": { "type": "string", "enum": ["USD", "EUR", "SEK"] }
},
"required": ["invoice_id", "amount", "currency"]
},
"ttl_seconds": 1800,
"on_expire": "notify"
}curl -X POST https://api.getstack.run/v1/dropoffs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_op_abc123" \
-d '{
"from_agent": "agt_7kx9m2nq4p",
"to_agent": "agt_3fh8j1kw6r",
"schema": {
"type": "object",
"properties": {
"invoice_id": { "type": "string" },
"amount": { "type": "number" }
},
"required": ["invoice_id", "amount"]
},
"ttl_seconds": 1800
}'{
"id": "dof_9xm3kR7wL2",
"operator_id": "op_abc123",
"from_agent_id": "agt_7kx9m2nq4p",
"to_agent_id": "agt_3fh8j1kw6r",
"status": "created",
"schema": {
"type": "object",
"properties": {
"invoice_id": { "type": "string" },
"amount": { "type": "number" }
},
"required": ["invoice_id", "amount"]
},
"on_expire": "notify",
"mission_id": null,
"deposited_bytes": 0,
"created_at": "2026-04-15T10:30:00.000Z",
"deposited_at": null,
"collected_at": null,
"expires_at": "2026-04-15T11:00:00.000Z"
}Deposit a payload into a created drop-off. The payload is validated against the drop-off's JSON Schema using Ajv. If validation fails, the deposit is rejected with detailed errors. The payload is encrypted with KMS before storage.
{
"agent_id": "agt_7kx9m2nq4p",
"passport_jti": "pas_active123",
"payload": {
"invoice_id": "INV-2026-0042",
"amount": 1250.00,
"currency": "USD"
}
}curl -X POST https://api.getstack.run/v1/dropoffs/dof_9xm3kR7wL2/deposit \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_op_abc123" \
-d '{
"agent_id": "agt_7kx9m2nq4p",
"payload": {
"invoice_id": "INV-2026-0042",
"amount": 1250.00,
"currency": "USD"
}
}'Schema validation is a hard gate. There is no way to bypass it or deposit data that does not conform to the declared schema. This ensures data integrity across the producer-consumer boundary.
Collect the payload from a deposited drop-off. The request must name the designated consumer in agent_id. After successful collection, the encrypted payload is permanently wiped from storage.
{
"agent_id": "agt_3fh8j1kw6r"
}curl -X POST https://api.getstack.run/v1/dropoffs/dof_9xm3kR7wL2/collect \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_op_abc123" \
-d '{
"agent_id": "agt_3fh8j1kw6r"
}'{
"payload": {
"invoice_id": "INV-2026-0042",
"amount": 1250.00,
"currency": "USD"
}
}Collection is a one-time operation. Once data is collected, it is permanently deleted from STACK's storage. The consumer receives the payload in the response and is responsible for handling it from that point forward.
Retrieve the current status and metadata for a drop-off. This never returns the actual payload or its encrypted envelope. Account credentials can read any account drop-off; agent credentials can read only drop-offs where that agent is producer or consumer.
curl https://api.getstack.run/v1/dropoffs/dof_9xm3kR7wL2 \
-H "Authorization: Bearer sk_live_op_abc123"Operator keys and OAuth tokens list all drop-offs for the account. Agent JWTs and Passports list only drop-offs where the authenticated agent is producer or consumer.
curl https://api.getstack.run/v1/dropoffs \
-H "Authorization: Bearer sk_live_op_abc123"Manually expire a drop-off before its TTL elapses. This transitions the drop-off to the expired state and wipes any deposited payload data. Account credentials may expire any active account drop-off; agent credentials may expire only a drop-off they produce.
curl -X POST https://api.getstack.run/v1/dropoffs/dof_9xm3kR7wL2/expire \
-H "Authorization: Bearer sk_live_op_abc123"Drop-offs are ephemeral by design. A background worker process monitors active drop-offs and transitions expired ones to the expired state. When a drop-off expires:
Creating a drop-off uses one action from the shared monthly allowance. Deposit and collection do not use another action.