# API Contract

The Supply-Y API is Agent-facing. It provides a consistent control plane for identity, Skills, keys, Package lifecycle, threads, notifications and audit across Native and Catena-X transport modes.

## Current status

The 21 operations below are the complete current 1.0 Agent API contract. A machine-readable OpenAPI 3.1.1 document is available at [`/openapi.json`](/openapi.json), and the [endpoint reference](#endpoint-reference) renders the same contract with validated examples. The release gate checks one-to-one parity between this page and OpenAPI and validates all 29 committed request and response examples. The [TypeScript SDK](/docs/sdk) exposes all 21 operations from a publish-ready reference package. A public hosted API and registry-published SDK are not yet generally available.

## API conventions

- Base path: `/v1`
- Media type: `application/json`
- Authentication: short-lived OAuth 2.0 access token
- Production client binding: mTLS or private-key JWT
- Request tracing: `X-Correlation-ID`
- Mutation deduplication: `Idempotency-Key`
- Time format: ISO 8601 UTC
- Identifiers: opaque strings with documented object prefixes
- Pagination: cursor-based for collection endpoints

Every mutation is idempotent within the authenticated organization, endpoint and idempotency key. Retrying a timed-out request returns the original operation instead of creating a second Package.

## Identity, Skills and keys

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `/v1/agents/register` | Register Agent capabilities and public keys |
| `GET` | `/v1/agents/{agent_id}` | Read verified status and compatibility |
| `POST` | `/v1/agents/{agent_id}/keys` | Register a distinct replacement public key |
| `POST` | `/v1/agents/{agent_id}/keys/{key_id}/revoke` | Record revocation time, trust cutoff and reason |
| `GET` | `/v1/skills` | List compatible signed Skills |
| `GET` | `/v1/skills/{skill_id}/releases/{version}` | Resolve a signed Skill release |
| `GET` | `/v1/directory/agents/{agent_id}/keys` | Retrieve verified recipient public keys |
| `GET` | `/v1/directory/notification-keys` | Retrieve Supply-Y webhook-signing public keys to pin |

The key directory response is versioned and timestamped. `revoked_at` means when Supply-Y recorded the event; `invalid_from` means the earliest Package creation time affected by the revocation. Historical verification requires matching audit evidence that the Package was accepted before the applicable cutoff. Private keys and private-key retention status remain customer-controlled and are never returned by this API.

## Policy receipts

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `/v1/policy-receipts` | Record a sender-signed claim that local checks ran before Package creation |
| `GET` | `/v1/policy-receipts/{policy_receipt_id}` | Read the authorized signed claim and its Package-eligibility decision |

The receipt contains identifiers, versions, digests, five bounded check outcomes and an approval outcome. It contains no Package plaintext, source rows, field values or model reasoning. The sender signs the RFC 8785 canonical receipt without `signature`; Supply-Y resolves the registered Agent key and verifies identity and integrity.

`signature_status: verified` means the registered sender signed the exact claim. `package_authorization: eligible` means all required check IDs passed, required human approval is present, the receipt predates Package creation and its sender, recipient, Skill, Policy, Package and content digest match. Neither result proves that the hidden business facts are true. `POST /v1/packages` rejects a missing, ineligible or mismatched policy receipt.

## Packages and threads

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `/v1/packages` | Create a Native or Catena-X transfer |
| `GET` | `/v1/packages/{package_id}` | Read authorized state and ciphertext location |
| `POST` | `/v1/packages/{package_id}/receipts` | Record received, opened, rejected or failed |
| `POST` | `/v1/packages/{package_id}/responses` | Create a response in the same thread |
| `POST` | `/v1/packages/{package_id}/revoke` | Request revocation before access where possible |
| `GET` | `/v1/threads/{thread_id}` | Read ordered Package metadata and state |

The API never accepts raw ERP datasets for a normal exchange. In Native Mode the business body is client-encrypted ciphertext. In Catena-X Mode the request contains transfer references and integrity metadata instead of a duplicate payload.

In Native Mode, `POST /v1/packages` receives the Flattened JWS JSON object defined by the [Cryptographic Profile](/docs/crypto). After sender verification, its payload decodes to readable routing metadata plus a two-recipient General JWE object. Supply-Y never receives the inner plaintext object or either recipient's private key.

## Notifications and audit

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `/v1/webhook-endpoints` | Register a signed webhook destination |
| `GET` | `/v1/notifications` | Poll pending lifecycle events |
| `POST` | `/v1/notifications/{notification_id}/ack` | Acknowledge processing |
| `GET` | `/v1/audit/threads/{thread_id}` | Read authorized immutable event history |
| `GET` | `/v1/audit/packages/{package_id}` | Read integrity and delivery evidence |

Webhook deliveries are signed, timestamped and assigned delivery and event IDs. Receivers must verify the signature, reject stale timestamps and deduplicate stable event IDs. A webhook failure does not roll back Package acceptance; delivery retries independently from the durable event stream.

The complete [Events And Webhooks](/docs/events) profile defines the event envelope, stable event and delivery identifiers, exact retry schedule, out-of-order recovery and acknowledgement semantics. Receivers deduplicate by `event_id`, because a manual replay has a new `delivery_id` while preserving the original event identity.

Webhook signatures follow [RFC 9421](https://www.rfc-editor.org/rfc/rfc9421.html). The normative profile covers the method, target authority, target path, RFC 9530 content digest, content type, delivery ID, event ID and delivery attempt. A `204` means the receiver durably stored the event in its local inbox; it is not evidence that the business Package was opened or processed.

## Standard error object

Errors use the `application/problem+json` model from [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html). They are machine-readable and do not echo encrypted content or secrets.

```json
{
  "type": "https://supply-y.example/problems/version-incompatible",
  "title": "Protocol version is not supported by the recipient",
  "status": 409,
  "code": "protocol_version_incompatible",
  "correlation_id": "corr_01J...",
  "retryable": false,
  "details": {
    "supported_versions": ["supply-y/1.0"]
  }
}
```

Expected categories include authentication, authorization, recipient capability, version compatibility, duplicate idempotency, invalid state transition, expired Package, rate limit and transport failure.

## Package state and partial failure

Package delivery is a durable state machine, not one long synchronous request.

```text
accepted -> encrypted_available / transfer_started -> delivered -> received -> opened -> responded
```

Secondary work is independent. If audit succeeds and notification fails, notification retries without replaying the Package. If recipient processing fails, the sender's accepted state is preserved and the recipient can retry safely.

## Standards profile

- [OpenAPI 3.1.1](https://spec.openapis.org/oas/v3.1.1.html) describes the HTTP contract in a broadly supported tool version.
- [RFC 9700](https://www.rfc-editor.org/rfc/rfc9700.html) is the OAuth 2.0 security baseline.
- [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457.html) defines API problem details.
- [RFC 9421](https://www.rfc-editor.org/rfc/rfc9421.html) defines HTTP Message Signatures for webhook delivery.

Package encryption and exchange-envelope signature algorithms remain a separate protocol profile and are not implied by the HTTP standards above. Business objects do not carry self-referential hash, signature or transport-routing fields.

## Catena-X transport

When both organizations have an approved EDC connection, the Exchange Orchestrator selects Catena-X for the entire thread. The sender publishes the encrypted and signed Package as one EDC asset, then submits a signed control manifest containing the authenticated Package metadata, connector and asset IDs, the RFC 9530 digest of the exact asset bytes, and any available contract-agreement and transfer-process IDs. The sender signature covers the RFC 8785 canonical control manifest without the `sender_signature` field.

Supply-Y records that manifest, receipts and normalized state. The recipient verifies the EDC asset digest before verifying and decrypting the Package. The payload travels once through the EDC data plane and is not copied into Native Package storage.

---

Canonical HTML: [Agent API Contract](https://supply-y.net/docs/api)
Agent documentation index: [llms.txt](https://supply-y.net/llms.txt)
