# Native HTTP API

This reference describes the native HTTP binding implemented by `aipd` 1.0.
The generic message endpoint carries complete AIP envelopes. Ergonomic
operational routes accept or return the corresponding native body objects.

## Media Types and Time

- The normative media type for a complete native envelope is
  `application/aip+json`.
- The current `aipd` Axum JSON routes also accept structured JSON requests and
  return `application/json`, including on the generic envelope endpoint. Strict
  response/request media-type alignment remains an implementation conformance
  item; see [Implementation Status](implementation-status.md).
- Ergonomic operational JSON responses use `application/json`.
- Follow-mode event responses use `text/event-stream`.
- Timestamps are RFC 3339 UTC values.
- Identifiers are opaque strings. Clients must not parse embedded time or
  topology from them.

## Authentication

Native operational routes require the deployment's native HTTP identity. A
common client sends:

```http
Authorization: Bearer TOKEN
```

Signed-envelope deployments authenticate the generic message path with the
configured signer binding. A trusted edge may use mTLS, OAuth, or workload
identity and inject server-owned principal context.

Unauthenticated traffic is allowed only by explicit loopback development
configuration.

## Service Endpoints

| Method | Path | Purpose | Auth |
|---|---|---|---|
| `GET` | `/` | Process health summary | Deployment-defined |
| `GET` | `/health` | Liveness | Deployment-defined |
| `GET` | `/ready` | Runtime readiness | Deployment-defined |
| `GET` | `/metrics` | Prometheus metrics | Protect at the deployment edge |
| `GET` | `/aip/v1/health` | Versioned health alias | Deployment-defined |
| `GET` | `/aip/v1/manifest` | Filtered participant manifest | Deployment-defined |
| `POST` | `/aip/v1/messages` | Send any native AIP envelope | Required in production |

### Manifest filters

`GET /aip/v1/manifest` accepts `capability_id`, `resource_kind`, `profile`,
`risk`, `side_effect`, `requires_approval`, `supports_streaming`, and
`supports_transactions`. Repeatable values may be expressed according to the
HTTP client; the daemon normalizes supported filters into `ManifestFilter`.

## Action Endpoints

| Method | Path | Purpose |
|---|---|---|
| `POST` | `/aip/v1/actions` | Submit a complete envelope with an `action` body |
| `GET` | `/aip/v1/actions` | List durable action views |
| `GET` | `/aip/v1/actions/{action_id}` | Read action status |
| `GET` | `/aip/v1/actions/{action_id}/result` | Read or briefly wait for the final result |
| `GET` | `/aip/v1/actions/{action_id}/events` | Read or follow action events |
| `GET` | `/aip/v1/actions/{action_id}/chunks` | Read or follow stream chunks |
| `POST` | `/aip/v1/actions/{action_id}/cancel` | Request cancellation |

Action list filters are `state`, `capability_id`, `session_id`, `principal_id`,
`tenant_id`, `approval_id`, `transaction_id`, `cursor`, and `limit`. Set
`include_results=true` or `include_receipts=true` only when needed.

Status parameters are `tenant_id`, `include_result`, `include_receipts`,
`include_chunks`, and `wait_ms`. `wait_ms` is bounded to 30,000.

Event parameters are `tenant_id`, `cursor`, `limit`, `kind` or `kinds`,
`include_chunks`, and `follow`. `follow=true` switches to SSE. A
`Last-Event-ID` header may provide the cursor when no query cursor is supplied.

Cancellation accepts an optional JSON body:

```json
{
  "reason": "The customer withdrew the request"
}
```

## Global Events

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/events` | Read or follow authorized global events |

Parameters are `cursor`, `limit`, `kind` or `kinds`, and `follow`. Event
visibility is constrained by the authenticated principal and tenant.

## Session Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/sessions` | List sessions |
| `GET` | `/aip/v1/sessions/{session_id}` | Read one session |
| `POST` | `/aip/v1/sessions/{session_id}/close` | Close a session |
| `POST` | `/aip/v1/sessions/{session_id}/resume` | Resume and replay a session |

The implementation also accepts `POST /aip/v1/sessions/{session_id}:close` and
`:resume`. New clients should use the slash form.

Session list filters are `principal_id`, `status`, `cursor`, and `limit`.
Resume accepts `resume_token` and `last_event_cursor`; the returned token
replaces the one supplied.

## Approval Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/approvals` | List approval records |
| `GET` | `/aip/v1/approvals/{approval_id}` | Read one approval record |

List filters are `status`, `approver`, `requester`, `tenant_id`, `cursor`, and
`limit`. Optional expansions are `include_action_status` and
`include_receipts`.

One-record reads also accept `include_evidence_payload`. This expansion exposes
sensitive governed input and requires dedicated export and sensitive-data
authority.

Submit `ApprovalRequest` and `ApprovalDecision` messages through
`POST /aip/v1/messages` or the CLI.

## Transaction Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/transactions/{transaction_id}` | Read by transaction id |
| `GET` | `/aip/v1/transactions/by-plan/{plan_id}` | Read by plan id |
| `GET` | `/aip/v1/transactions/by-action/{action_id}` | Read by action id |

All forms accept `tenant_id`, `include_result`, and `include_receipts`.
Transactional execution is submitted as a native `TransactionRequest` or an
`Action` with transaction context.

## Callback Delivery Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/callback-deliveries` | List durable delivery records |
| `GET` | `/aip/v1/callback-deliveries/{delivery_id}` | Read one delivery |

List filters are `action_id`, `status`, `profile`, `target`, `tenant_id`,
`cursor`, `limit`, and `include_receipts`.

## Receipt and Audit Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/receipts/{chain_id}` | Read a receipt chain |
| `GET` | `/aip/v1/receipts/by-receipt/{receipt_id}` | Find a chain by receipt |
| `GET` | `/aip/v1/audit/events` | Query audit records |

Audit filters are `action_id`, `session_id`, `principal_id`, `tenant_id`,
`transaction_id`, `from`, `to`, `cursor`, and `limit`. Set
`include_receipts=true` to include linked chains. Set `export=true` only for an
authorized evidence export.

## Resource Endpoints

| Method | Path | Purpose |
|---|---|---|
| `GET` | `/aip/v1/resources` | List visible resources |
| `GET` | `/aip/v1/resources/{resource_id}` | Read one resource |

List filters are `capability_id`, `kind`, `tenant_id`, `cursor`, and `limit`.
Read parameters are `tenant_id`, `version`, and comma-separated `accept` values.

## Native WebSocket

`GET /aip/v1/ws` upgrades an authenticated request to the native WebSocket
binding. Each text frame carries one encoded AIP envelope. Implementations use
heartbeat and bounded multiplexing rules from the normative specification.

## Compatibility Endpoints

| Protocol | Endpoints |
|---|---|
| MCP Streamable HTTP | `/mcp`, `/mcp/v1`, `/aip/v1/mcp` |
| MCP protected-resource metadata | `/.well-known/oauth-protected-resource`, `/.well-known/oauth-protected-resource/mcp` |
| MCP legacy HTTP+SSE | `/mcp/legacy/sse`, `/mcp/legacy/messages` |
| A2A compatibility | `/.well-known/agent.json`, `/.well-known/agent-card.json`, `/a2a/agent-card`, `/a2a`, `/a2a/v1`, `/aip/v1/a2a` |
| Cal.diy webhook ingress | `/connectors/cal-diy/webhooks/{subscription_id}` |

Compatibility endpoints have their own protocol media types, session rules,
and authentication. They do not change native AIP semantics.

## Pagination and Cursors

`limit` must be between 1 and 1000. Cursors are opaque and scoped to the query,
identity, tenant, and retention window. Clients must not manufacture or decode
them.

## Errors

Native failures use `ProtocolError`. See [Errors](errors.md) for categories,
retry decisions, and HTTP status mapping.
