{
  "schemaVersion": "1.0",
  "title": "Connector fleet HTTP API",
  "description": "This reference describes the HTTP contracts used inside an AIP connector fleet. Use it to identify the correct process and route, construct a signed request, and interpret route, lease, replay, and capacity failures.",
  "canonical": "https://getaip.org/docs/reference/connector-fleet-api",
  "route": "/docs/reference/connector-fleet-api",
  "source": "docs/reference/connector-fleet-api.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "API Reference",
  "documentType": "Reference",
  "language": "en",
  "downloads": {
    "md": "/docs/download/reference/connector-fleet-api.md",
    "txt": "/docs/download/reference/connector-fleet-api.txt",
    "json": "/docs/download/reference/connector-fleet-api.json",
    "pdf": "/docs/download/reference/connector-fleet-api.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Connector fleet HTTP API\ndescription: Look up connector-host, lifecycle-control, and central-ingress contracts\nkind: reference\naudience: developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\n---\n\n# Connector fleet HTTP API\n\nThis reference describes the HTTP contracts used inside an AIP connector\nfleet. Use it to identify the correct process and route, construct a signed\nrequest, and interpret route, lease, replay, and capacity failures.\n\nThe contract applies to source revision\n`97be86e9efedf07ecf1783b03800f683f107fb04`. It is an implementation boundary\nbetween trusted fleet components. It is not a public connector-catalog\nadministration API and does not add fields to AIP 1.0.\n\n## Three HTTP planes\n\n| Plane | Caller | Server | Purpose |\n|---|---|---|---|\n| Connector data | Central `aipd` | Connector host | Deliver a route-pinned action or cancellation and receive a signed result |\n| Host lifecycle | Connector host | Connector control plane | Register, renew, drain, or take one pre-provisioned replica offline |\n| Central ingress | Connector host | Central `aipd` | Publish provider events or return stream chunks for an assigned action |\n\nEach plane has its own signer and authorization checks. Bearer authentication\nfor the public native API does not replace these signatures. Operational\nhealth, readiness, manifest, and metrics routes have no application\nauthentication in their process routers; protect them at the deployment edge.\n\n## Connector-host data plane\n\nOne connector-host process exposes five routes:\n\n| Method | Path | Response |\n|---|---|---|\n| `GET` | `/health` | Process-liveness JSON |\n| `GET` | `/ready` | Lease, drain, storage, and connector readiness JSON |\n| `GET` | `/metrics` | Connector-host Prometheus text |\n| `GET` | `/aip/v1/manifest` | The immutable host-bound `Manifest` |\n| `POST` | `/aip/v1/messages` | A signed response `Envelope` |\n\nThe admitted public endpoint must be an absolute URL ending exactly in\n`/aip/v1/messages`, without credentials, query, or fragment. HTTPS is required\nexcept for explicitly enabled loopback development. The default request-body\nlimit is 4 MiB.\n\n### Health and readiness\n\n`GET /health` reports process liveness only:\n\n```json\n{\n  \"status\": \"ok\",\n  \"protocol\": \"AIP\",\n  \"version\": \"1.0\",\n  \"service\": \"aip-connector-host\"\n}\n```\n\n`GET /ready` returns HTTP `200` only when all four conditions are true:\n\n- the host is not draining;\n- its registry lease has not expired;\n- durable runtime storage passes its probe; and\n- the connector-specific health probe is ready.\n\nOtherwise it returns HTTP `503`. The body exposes `status`, `lease_valid`,\n`draining`, a `runtime` object with durability, readiness, detail, and recovery\nstate, and a `connector` readiness object. Readiness does not prove that an\nexternal provider request succeeded.\n\n### Message authentication and route pinning\n\n`POST /aip/v1/messages` accepts a complete AIP `Envelope`. Before dispatch, the\nhost verifies all of these boundaries:\n\n1. The JSON passes the `Envelope` schema and decodes successfully.\n2. The Ed25519 envelope signature resolves to the configured central gateway\n   DID.\n3. `from` matches the configured gateway principal, kind, and trust domain.\n4. `to` matches this host principal.\n5. `security.connector_route` matches the admitted tenant, instance, replica,\n   version, and manifest digest.\n6. An action or cancellation matches the route's action and capability.\n7. Any credential revision and approval authorization remains valid locally.\n\nThe central dispatcher places these fields in `security.connector_route`:\n\n| Field | Meaning |\n|---|---|\n| `action_id`, `capability_id` | Durable work coordinates |\n| `tenant_id` | Verified tenant selected by the central runtime |\n| `instance_id`, `replica_id`, `version_id` | Pinned fleet destination |\n| `manifest_digest` | Admitted immutable capability contract |\n| `catalog_revision`, `binding_policy_revision` | Catalog and binding snapshot |\n| `credential_revision_ref`, `quota_policy_ref` | Pinned policy references |\n| `replica_health_revision`, `fence_token` | Assignment and lease fences |\n| `original_mode` | Client mode before the remote-hop projection |\n| `approval_authorization` | Optional terminal approval record verified by the gateway |\n\nThe deployed remote dispatcher sends actions and action-scoped cancellations.\nIt projects verified tenant identity into the action. An async client action is\nexecuted synchronously at the host hop because the central runtime owns durable\nqueueing. A streaming action retains streaming mode and receives only the\nfixed central callback destination.\n\nThe host signs every post-decode success or protocol-error envelope with its\nconfigured host key. It also correlates the response to the request. The\ncentral dispatcher authenticates the endpoint and verifies the expected host\nprincipal, DID, and trust domain before accepting the response.\n\n### Host message errors\n\n| HTTP | Code | Condition |\n|---:|---|---|\n| `400` | `schema.envelope.invalid` | JSON does not pass the envelope schema |\n| `400` | `envelope.decode.invalid` | Schema-valid JSON cannot decode as an envelope |\n| `401` | `connector_host.route_mismatch` | Gateway signature or sender is not trusted |\n| `403` | `connector_host.route_mismatch` | Recipient or pinned route does not match this host |\n| `503` | `connector_host.not_ready` | Host is draining or its lease or health is invalid |\n| `429` | `connector_host.capacity` | Local action concurrency is exhausted |\n\nSchema and decode errors occur before a trustworthy request envelope exists,\nso those responses are unsigned input errors. Later errors are correlated and\nsigned. Credential or approval-journal checks can add a more specific `403` or\n`503` error.\n\n## Host lifecycle control plane\n\nThe standalone connector control plane exposes:\n\n| Method | Path | Purpose |\n|---|---|---|\n| `GET` | `/health` | Process liveness |\n| `GET` | `/ready` | Registry schema, revision, and pool readiness |\n| `GET` | `/metrics` | Fixed-cardinality registry pool snapshot as JSON |\n| `POST` | `/aip/v1/connector-control` | Signed replica lifecycle transition |\n\n`GET /ready` returns HTTP `200` with `schema_version`, `catalog_revision`, and\n`pools` only when the restricted registry connection is healthy and the\ninstalled schema is current. It returns `503` with `schema_ok` and `catalog_ok`\notherwise. Unlike connector-host metrics, control-plane `/metrics` is a JSON\npool snapshot, not Prometheus text.\n\n### Signed lifecycle request\n\nThe request body has a signed outer wrapper:\n\n```json\n{\n  \"request\": {\n    \"request_id\": \"msg_0190c42f2d5a70008000000000000001\",\n    \"issued_at\": \"2026-07-26T12:00:00Z\",\n    \"expires_at\": \"2026-07-26T12:00:30Z\",\n    \"signer_did\": \"did:key:z6Mk...\",\n    \"command\": {\n      \"operation\": \"heartbeat\",\n      \"payload\": {\n        \"replica_id\": \"crepl_booking_region_a_one\",\n        \"previous_sequence\": 17,\n        \"in_flight\": 3,\n        \"connector_ready\": true\n      }\n    }\n  },\n  \"signature\": \"base64-ed25519-signature\"\n}\n```\n\n`signature` is standard-base64 Ed25519 over canonical JSON for the `request`\nobject. `signer_did` must equal the DID pre-provisioned for that replica. The\ncontrol plane rejects an invalid signature, an unknown replica, or a signer\nthat does not match the registry record.\n\nThe accepted clock window is deliberately small. The request lifetime cannot\nexceed 30 seconds, `expires_at` must be after `issued_at` and the current time,\nand `issued_at` can be at most five seconds in the future.\n\n### Lifecycle commands\n\n| Operation | Payload | Successful outcome |\n|---|---|---|\n| `register` | `ConnectorHostRegistration` | New `lease` |\n| `heartbeat` | `replica_id`, `previous_sequence`, `in_flight`, `connector_ready` | Renewed `lease` |\n| `drain` | `replica_id`, `previous_sequence` | Renewed lease in draining state |\n| `offline` | `replica_id`, `previous_sequence` | `offline` |\n\nRegistration contains the complete proposed replica record plus\n`manifest_digest`, `artifact_digest`, `tenant_id`, `config_revision`,\n`secret_provider_ref`, and `capability_count`. The replica record carries its\nendpoint, peer principal and DID, trust domain, transport profile, topology,\ncapacity, and initial health state. The control plane compares this proposal\nwith the pre-admitted version, instance, and offline replica identity.\n\n`previous_sequence` is a monotonic lease fence. A heartbeat cannot report more\nin-flight work than admitted capacity. `connector_ready=false` moves the\nreplica offline instead of renewing it as ready. Drain stops new assignments\nwhile allowing already pinned work to finish.\n\n### Signed lifecycle response\n\nEvery normal or rejected operation returns a signed wrapper containing\n`response` and `signature`. The response repeats `request_id`, has its own\n30-second `issued_at` and `expires_at` window, identifies the control-plane\n`signer_did`, and carries one outcome:\n\n| HTTP | Outcome | Meaning |\n|---:|---|---|\n| `200` | `{\"status\":\"lease\",\"lease\":{\"sequence\":n,\"expires_at\":[...]}}` | Register, heartbeat, or drain committed |\n| `200` | `{\"status\":\"offline\"}` | Offline transition committed |\n| `403` | `{\"status\":\"rejected\",\"code\":\"connector_control.rejected\",...}` | Admission or configuration rejection; not retryable |\n| `503` | `{\"status\":\"rejected\",\"code\":\"connector_control.unavailable\",...}` | Storage or control service unavailable; retryable |\n\nThe host verifies the response request ID, trusted control-plane DID, time\nwindow, and signature before applying a lease. A response-signing failure is\nan unsigned HTTP `500` input-style error because no signed response can be\nproduced.\n\nThe wrapper's `issued_at` and `expires_at` fields are RFC 3339 strings. At this\nrevision, `ConnectorHostLease.expires_at` uses the default `time` serialization\ninstead: a nine-item array of year, ordinal day, hour, minute, second,\nnanosecond, and three UTC-offset components. Clients must not assume the lease\nfield is also an RFC 3339 string.\n\nRequest IDs are replay protected. Retrying the exact signed bytes after a lost\nresponse is safe while that request remains the last committed lifecycle\ntransition. Reusing the ID with different content, or replaying an older\ntransition after a later state, is rejected.\n\nThe control endpoint must be an absolute HTTPS URL ending exactly in\n`/aip/v1/connector-control`, with no credentials, query, or fragment. Explicit\nloopback development may use HTTP. Request and response bodies are limited to\n64 KiB.\n\n## Central connector ingress\n\nCentral `aipd` exposes two canonical connector-origin routes:\n\n| Method | Path | Canonical body |\n|---|---|---|\n| `POST` | `/aip/v1/connector-events` | `EventStream` envelope for provider events |\n| `POST` | `/aip/v1/connector-callbacks` | `StreamChunk` envelope for a streaming action |\n\nThe connector host requires those exact paths when configuring its event and\ncallback publishers. At this revision both routes mount the same shared\nhandler, which selects behavior from the envelope body rather than the URL.\nPublishers should still use the canonical path for the body family.\n\nNeither route uses native bearer middleware. The ingress validates the AIP\nenvelope schema, exact central recipient, envelope signature, sender principal,\nregistry state, tenant, version, manifest, attestation, and an active replica\nlease before storing content. Accepted responses are signed central envelopes\ncorrelated to the request.\n\n### Provider-event envelope\n\nAn event publisher sends a non-empty `EventStream` with no `next_cursor` and\nplaces these fields in `security.connector_event`:\n\n| Field | Meaning |\n|---|---|\n| `tenant_id` | Tenant fixed by the enabled connector instance |\n| `instance_id`, `replica_id`, `version_id` | Originating fleet coordinates |\n| `manifest_digest` | Active admitted version digest |\n| `lease_sequence` | Exact current replica health revision |\n| `channel_id` | Channel declared by the version manifest |\n\nThe replica may be ready or draining, but its lease must remain current. The\ningress binds each event actor to the signed host, writes verified tenant and\nconnector provenance into event data, and then appends it to the durable event\nlog. Reusing an event ID is accepted only when retained semantic content is\nequivalent; different content returns\n`connector_event.idempotency_conflict`.\n\n### Stream-callback envelope\n\nA callback publisher sends one `StreamChunk`. Its\n`security.connector_callback` object contains the complete assigned route:\n\n| Field group | Fields |\n|---|---|\n| Work | `action_id`, `capability_id`, `tenant_id` |\n| Destination | `instance_id`, `replica_id`, `version_id`, `manifest_digest` |\n| Policy | `catalog_revision`, `binding_policy_revision`, `credential_revision_ref`, `quota_policy_ref` |\n| Fences | `replica_health_revision`, `fence_token` |\n| Mode | `original_mode` equal to `streaming` |\n\nThe chunk action ID must equal the route action ID. All durable assignment\nfields must match the central route resolver. The current replica must still\nmatch the assigned endpoint, identity, DID, trust domain, transport profile,\ninstance, and version. A lease renewal may advance the live health revision,\nbut it cannot invalidate the assignment's other fences.\n\n### Ingress defaults and responses\n\n| Bound | Default |\n|---|---:|\n| Signed envelope | 4 MiB |\n| Events per event envelope | 100 |\n| One enriched event | 256 KiB |\n| One stream chunk | 256 KiB |\n| Concurrent ingress operations | 128 |\n| Maximum event age | 24 hours |\n| Maximum future clock skew | 5 minutes |\n| Maximum stream-callback age | 5 minutes |\n\nSuccessful event ingress returns a signed `EventStream` containing the stored\nevents. Successful stream ingress returns the signed `EventStream` produced by\nthe central stream sink. The principal error cases are:\n\n| HTTP | Code | Retry |\n|---:|---|---|\n| `404` | `connector_event.not_configured` | No |\n| `400` | `schema.envelope.invalid` or `envelope.decode.invalid` | No |\n| `400` | `connector_event.invalid` or `connector_event.idempotency_conflict` | No |\n| `401` | `connector_event.not_authorized` | No |\n| `503` | `connector_event.capacity` | Yes, after 100 ms |\n| `503` | `connector_event.unavailable` | Yes, after 1,000 ms |\n\nAn error produced after envelope decoding is signed when the central ingress\nsigner is available. Pre-decode and not-configured errors use the ordinary\nnative error response.\n\n## Request-flow summary\n\n| Flow | Sequence |\n|---|---|\n| Start or renew a host | Host signs lifecycle request → control plane verifies pre-provisioned identity and replay → registry transition commits → control plane signs lease → host verifies and applies lease |\n| Invoke an action | Runtime resolves and fences route → `aipd` signs pinned envelope → host verifies gateway, route, lease, credential, and approval → connector executes → host signs result → central dispatcher verifies it |\n| Publish a provider event | Host durably stages event → host signs event stream and route → central ingress verifies current registry state → event log accepts or identifies an idempotent replay |\n| Stream a result | Central action carries fixed callback route → host signs each chunk → ingress compares the complete durable assignment → runtime stores and exposes the stream |\n\n## Surface boundaries\n\nThis API does not expose catalog writes, connector admission, credential\nmaterial, or registry database access to a connector host. Client-facing\nactions, queries, sessions, approvals, and audit routes remain in the [native\nHTTP API](http-api.md). Complete deployment settings belong to [connector-host\nconfiguration](connector-host-configuration.md), and operational transitions\nbelong to [connector-host lifecycle](../guides/connector-host-lifecycle.md).\n\nTransport retry, destination, and response-authentication rules are detailed\nin [transport bindings](transport-bindings.md). Normative envelope and body\ndefinitions remain in [JSON schemas](../spec/schemas.md).\n\n## Related documentation\n\n- [Deploy a connector fleet](../guides/deploy-connector-fleet.md)\n- [Errors and retry decisions](errors.md)\n- [Identity and trust](../concepts/identity-and-trust.md)\n",
    "text": "Connector fleet HTTP API\n\nThis reference describes the HTTP contracts used inside an AIP connector\nfleet. Use it to identify the correct process and route, construct a signed\nrequest, and interpret route, lease, replay, and capacity failures.\n\nThe contract applies to source revision\n97be86e9efedf07ecf1783b03800f683f107fb04. It is an implementation boundary\nbetween trusted fleet components. It is not a public connector-catalog\nadministration API and does not add fields to AIP 1.0.\n\nThree HTTP planes\n\n| Plane | Caller | Server | Purpose |\n\n| Connector data | Central aipd | Connector host | Deliver a route-pinned action or cancellation and receive a signed result |\n| Host lifecycle | Connector host | Connector control plane | Register, renew, drain, or take one pre-provisioned replica offline |\n| Central ingress | Connector host | Central aipd | Publish provider events or return stream chunks for an assigned action |\n\nEach plane has its own signer and authorization checks. Bearer authentication\nfor the public native API does not replace these signatures. Operational\nhealth, readiness, manifest, and metrics routes have no application\nauthentication in their process routers; protect them at the deployment edge.\n\nConnector-host data plane\n\nOne connector-host process exposes five routes:\n\n| Method | Path | Response |\n\n| GET | /health | Process-liveness JSON |\n| GET | /ready | Lease, drain, storage, and connector readiness JSON |\n| GET | /metrics | Connector-host Prometheus text |\n| GET | /aip/v1/manifest | The immutable host-bound Manifest |\n| POST | /aip/v1/messages | A signed response Envelope |\n\nThe admitted public endpoint must be an absolute URL ending exactly in\n/aip/v1/messages, without credentials, query, or fragment. HTTPS is required\nexcept for explicitly enabled loopback development. The default request-body\nlimit is 4 MiB.\n\nHealth and readiness\n\nGET /health reports process liveness only:\n\n{\n  \"status\": \"ok\",\n  \"protocol\": \"AIP\",\n  \"version\": \"1.0\",\n  \"service\": \"aip-connector-host\"\n}\n\nGET /ready returns HTTP 200 only when all four conditions are true:\n• the host is not draining;\n• its registry lease has not expired;\n• durable runtime storage passes its probe; and\n• the connector-specific health probe is ready.\n\nOtherwise it returns HTTP 503. The body exposes status, leasevalid,\ndraining, a runtime object with durability, readiness, detail, and recovery\nstate, and a connector readiness object. Readiness does not prove that an\nexternal provider request succeeded.\n\nMessage authentication and route pinning\n\nPOST /aip/v1/messages accepts a complete AIP Envelope. Before dispatch, the\nhost verifies all of these boundaries:\n1. The JSON passes the Envelope schema and decodes successfully.\n2. The Ed25519 envelope signature resolves to the configured central gateway\n   DID.\n3. from matches the configured gateway principal, kind, and trust domain.\n4. to matches this host principal.\n5. security.connectorroute matches the admitted tenant, instance, replica,\n   version, and manifest digest.\n6. An action or cancellation matches the route's action and capability.\n7. Any credential revision and approval authorization remains valid locally.\n\nThe central dispatcher places these fields in security.connectorroute:\n\n| Field | Meaning |\n\n| actionid, capabilityid | Durable work coordinates |\n| tenantid | Verified tenant selected by the central runtime |\n| instanceid, replicaid, versionid | Pinned fleet destination |\n| manifestdigest | Admitted immutable capability contract |\n| catalogrevision, bindingpolicyrevision | Catalog and binding snapshot |\n| credentialrevisionref, quotapolicyref | Pinned policy references |\n| replicahealthrevision, fencetoken | Assignment and lease fences |\n| originalmode | Client mode before the remote-hop projection |\n| approvalauthorization | Optional terminal approval record verified by the gateway |\n\nThe deployed remote dispatcher sends actions and action-scoped cancellations.\nIt projects verified tenant identity into the action. An async client action is\nexecuted synchronously at the host hop because the central runtime owns durable\nqueueing. A streaming action retains streaming mode and receives only the\nfixed central callback destination.\n\nThe host signs every post-decode success or protocol-error envelope with its\nconfigured host key. It also correlates the response to the request. The\ncentral dispatcher authenticates the endpoint and verifies the expected host\nprincipal, DID, and trust domain before accepting the response.\n\nHost message errors\n\n| HTTP | Code | Condition |\n\n| 400 | schema.envelope.invalid | JSON does not pass the envelope schema |\n| 400 | envelope.decode.invalid | Schema-valid JSON cannot decode as an envelope |\n| 401 | connectorhost.routemismatch | Gateway signature or sender is not trusted |\n| 403 | connectorhost.routemismatch | Recipient or pinned route does not match this host |\n| 503 | connectorhost.notready | Host is draining or its lease or health is invalid |\n| 429 | connectorhost.capacity | Local action concurrency is exhausted |\n\nSchema and decode errors occur before a trustworthy request envelope exists,\nso those responses are unsigned input errors. Later errors are correlated and\nsigned. Credential or approval-journal checks can add a more specific 403 or\n503 error.\n\nHost lifecycle control plane\n\nThe standalone connector control plane exposes:\n\n| Method | Path | Purpose |\n\n| GET | /health | Process liveness |\n| GET | /ready | Registry schema, revision, and pool readiness |\n| GET | /metrics | Fixed-cardinality registry pool snapshot as JSON |\n| POST | /aip/v1/connector-control | Signed replica lifecycle transition |\n\nGET /ready returns HTTP 200 with schemaversion, catalogrevision, and\npools only when the restricted registry connection is healthy and the\ninstalled schema is current. It returns 503 with schemaok and catalogok\notherwise. Unlike connector-host metrics, control-plane /metrics is a JSON\npool snapshot, not Prometheus text.\n\nSigned lifecycle request\n\nThe request body has a signed outer wrapper:\n\n{\n  \"request\": {\n    \"requestid\": \"msg0190c42f2d5a70008000000000000001\",\n    \"issuedat\": \"2026-07-26T12:00:00Z\",\n    \"expiresat\": \"2026-07-26T12:00:30Z\",\n    \"signerdid\": \"did:key:z6Mk...\",\n    \"command\": {\n      \"operation\": \"heartbeat\",\n      \"payload\": {\n        \"replicaid\": \"creplbookingregionaone\",\n        \"previoussequence\": 17,\n        \"inflight\": 3,\n        \"connectorready\": true\n      }\n    }\n  },\n  \"signature\": \"base64-ed25519-signature\"\n}\n\nsignature is standard-base64 Ed25519 over canonical JSON for the request\nobject. signerdid must equal the DID pre-provisioned for that replica. The\ncontrol plane rejects an invalid signature, an unknown replica, or a signer\nthat does not match the registry record.\n\nThe accepted clock window is deliberately small. The request lifetime cannot\nexceed 30 seconds, expiresat must be after issuedat and the current time,\nand issuedat can be at most five seconds in the future.\n\nLifecycle commands\n\n| Operation | Payload | Successful outcome |\n\n| register | ConnectorHostRegistration | New lease |\n| heartbeat | replicaid, previoussequence, inflight, connectorready | Renewed lease |\n| drain | replicaid, previoussequence | Renewed lease in draining state |\n| offline | replicaid, previoussequence | offline |\n\nRegistration contains the complete proposed replica record plus\nmanifestdigest, artifactdigest, tenantid, configrevision,\nsecretproviderref, and capabilitycount. The replica record carries its\nendpoint, peer principal and DID, trust domain, transport profile, topology,\ncapacity, and initial health state. The control plane compares this proposal\nwith the pre-admitted version, instance, and offline replica identity.\n\nprevioussequence is a monotonic lease fence. A heartbeat cannot report more\nin-flight work than admitted capacity. connectorready=false moves the\nreplica offline instead of renewing it as ready. Drain stops new assignments\nwhile allowing already pinned work to finish.\n\nSigned lifecycle response\n\nEvery normal or rejected operation returns a signed wrapper containing\nresponse and signature. The response repeats requestid, has its own\n30-second issuedat and expiresat window, identifies the control-plane\nsignerdid, and carries one outcome:\n\n| HTTP | Outcome | Meaning |\n\n| 200 | {\"status\":\"lease\",\"lease\":{\"sequence\":n,\"expiresat\":[...]}} | Register, heartbeat, or drain committed |\n| 200 | {\"status\":\"offline\"} | Offline transition committed |\n| 403 | {\"status\":\"rejected\",\"code\":\"connectorcontrol.rejected\",...} | Admission or configuration rejection; not retryable |\n| 503 | {\"status\":\"rejected\",\"code\":\"connectorcontrol.unavailable\",...} | Storage or control service unavailable; retryable |\n\nThe host verifies the response request ID, trusted control-plane DID, time\nwindow, and signature before applying a lease. A response-signing failure is\nan unsigned HTTP 500 input-style error because no signed response can be\nproduced.\n\nThe wrapper's issuedat and expiresat fields are RFC 3339 strings. At this\nrevision, ConnectorHostLease.expiresat uses the default time serialization\ninstead: a nine-item array of year, ordinal day, hour, minute, second,\nnanosecond, and three UTC-offset components. Clients must not assume the lease\nfield is also an RFC 3339 string.\n\nRequest IDs are replay protected. Retrying the exact signed bytes after a lost\nresponse is safe while that request remains the last committed lifecycle\ntransition. Reusing the ID with different content, or replaying an older\ntransition after a later state, is rejected.\n\nThe control endpoint must be an absolute HTTPS URL ending exactly in\n/aip/v1/connector-control, with no credentials, query, or fragment. Explicit\nloopback development may use HTTP. Request and response bodies are limited to\n64 KiB.\n\nCentral connector ingress\n\nCentral aipd exposes two canonical connector-origin routes:\n\n| Method | Path | Canonical body |\n\n| POST | /aip/v1/connector-events | EventStream envelope for provider events |\n| POST | /aip/v1/connector-callbacks | StreamChunk envelope for a streaming action |\n\nThe connector host requires those exact paths when configuring its event and\ncallback publishers. At this revision both routes mount the same shared\nhandler, which selects behavior from the envelope body rather than the URL.\nPublishers should still use the canonical path for the body family.\n\nNeither route uses native bearer middleware. The ingress validates the AIP\nenvelope schema, exact central recipient, envelope signature, sender principal,\nregistry state, tenant, version, manifest, attestation, and an active replica\nlease before storing content. Accepted responses are signed central envelopes\ncorrelated to the request.\n\nProvider-event envelope\n\nAn event publisher sends a non-empty EventStream with no nextcursor and\nplaces these fields in security.connectorevent:\n\n| Field | Meaning |\n\n| tenantid | Tenant fixed by the enabled connector instance |\n| instanceid, replicaid, versionid | Originating fleet coordinates |\n| manifestdigest | Active admitted version digest |\n| leasesequence | Exact current replica health revision |\n| channelid | Channel declared by the version manifest |\n\nThe replica may be ready or draining, but its lease must remain current. The\ningress binds each event actor to the signed host, writes verified tenant and\nconnector provenance into event data, and then appends it to the durable event\nlog. Reusing an event ID is accepted only when retained semantic content is\nequivalent; different content returns\nconnectorevent.idempotencyconflict.\n\nStream-callback envelope\n\nA callback publisher sends one StreamChunk. Its\nsecurity.connectorcallback object contains the complete assigned route:\n\n| Field group | Fields |\n\n| Work | actionid, capabilityid, tenantid |\n| Destination | instanceid, replicaid, versionid, manifestdigest |\n| Policy | catalogrevision, bindingpolicyrevision, credentialrevisionref, quotapolicyref |\n| Fences | replicahealthrevision, fencetoken |\n| Mode | originalmode equal to streaming |\n\nThe chunk action ID must equal the route action ID. All durable assignment\nfields must match the central route resolver. The current replica must still\nmatch the assigned endpoint, identity, DID, trust domain, transport profile,\ninstance, and version. A lease renewal may advance the live health revision,\nbut it cannot invalidate the assignment's other fences.\n\nIngress defaults and responses\n\n| Bound | Default |\n\n| Signed envelope | 4 MiB |\n| Events per event envelope | 100 |\n| One enriched event | 256 KiB |\n| One stream chunk | 256 KiB |\n| Concurrent ingress operations | 128 |\n| Maximum event age | 24 hours |\n| Maximum future clock skew | 5 minutes |\n| Maximum stream-callback age | 5 minutes |\n\nSuccessful event ingress returns a signed EventStream containing the stored\nevents. Successful stream ingress returns the signed EventStream produced by\nthe central stream sink. The principal error cases are:\n\n| HTTP | Code | Retry |\n\n| 404 | connectorevent.notconfigured | No |\n| 400 | schema.envelope.invalid or envelope.decode.invalid | No |\n| 400 | connectorevent.invalid or connectorevent.idempotencyconflict | No |\n| 401 | connectorevent.notauthorized | No |\n| 503 | connectorevent.capacity | Yes, after 100 ms |\n| 503 | connectorevent.unavailable | Yes, after 1,000 ms |\n\nAn error produced after envelope decoding is signed when the central ingress\nsigner is available. Pre-decode and not-configured errors use the ordinary\nnative error response.\n\nRequest-flow summary\n\n| Flow | Sequence |\n\n| Start or renew a host | Host signs lifecycle request → control plane verifies pre-provisioned identity and replay → registry transition commits → control plane signs lease → host verifies and applies lease |\n| Invoke an action | Runtime resolves and fences route → aipd signs pinned envelope → host verifies gateway, route, lease, credential, and approval → connector executes → host signs result → central dispatcher verifies it |\n| Publish a provider event | Host durably stages event → host signs event stream and route → central ingress verifies current registry state → event log accepts or identifies an idempotent replay |\n| Stream a result | Central action carries fixed callback route → host signs each chunk → ingress compares the complete durable assignment → runtime stores and exposes the stream |\n\nSurface boundaries\n\nThis API does not expose catalog writes, connector admission, credential\nmaterial, or registry database access to a connector host. Client-facing\nactions, queries, sessions, approvals, and audit routes remain in the native\nHTTP API (http-api.md). Complete deployment settings belong to connector-host\nconfiguration (connector-host-configuration.md), and operational transitions\nbelong to connector-host lifecycle (../guides/connector-host-lifecycle.md).\n\nTransport retry, destination, and response-authentication rules are detailed\nin transport bindings (transport-bindings.md). Normative envelope and body\ndefinitions remain in JSON schemas (../spec/schemas.md).\n\nRelated documentation\n• Deploy a connector fleet (../guides/deploy-connector-fleet.md)\n• Errors and retry decisions (errors.md)\n• Identity and trust (../concepts/identity-and-trust.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "8cf502f0c45de2ffce13bce7a2e0bf478eda80023a116611ba018afbb7529d9d"
  }
}
