AIP Specification
Version 0.1.0 · Snapshot 2026-02-27 · Status: Draft
Overview
The Agent Intake Protocol (AIP) defines a standard interface for AI agents to discover, submit intake data to, and receive structured offers from business service endpoints. This document is the authoritative technical specification.
Terminology
| Term | Definition |
|---|---|
| Agent | An AI agent acting on behalf of a human user. |
| Provider | A business or service that implements AIP endpoints. |
| Manifest | The agent-intake.json file describing available intakes. |
| Intake | A structured data submission from an agent to a provider. |
| Soft-contract | A non-binding, structured offer returned by a provider. |
| Bind | The act of accepting an offer, converting it to an active relationship. |
| PII | Personally identifiable information (email, name, phone, etc.). |
Protocol Lifecycle
Stage 1: Discover
The agent sends an HTTP GET request to the provider's well-known path:
GET https://{domain}/.well-known/agent-intake.json
Accept: application/json
The provider MUST respond with a valid manifest (see Manifest Schema) and Content-Type: application/json.
Requirements:
- The path MUST be
/.well-known/agent-intake.jsonper RFC 8615. - The response MUST be valid JSON conforming to the manifest schema.
- CORS headers SHOULD be set to allow cross-origin agent access.
- HTTPS is REQUIRED for production endpoints. HTTP is acceptable for local development only.
Stage 2: Submit
The agent constructs an intake request and POSTs it to the intake endpoint specified in the manifest:
POST {intake.endpoint}
Content-Type: application/json
{
"aip_version": "0.1.0",
"agent": {
"id": "agent-instance-id",
"platform": "anthropic",
"consent_scope": ["intake", "offer"]
},
"intake_data": {
// Fields conforming to intake.input_schema
},
"session_id": "uuid-v4"
}
Requirements:
- The
intake_dataobject MUST conform to theinput_schemadeclared in the manifest. - The
session_idMUST be a UUID v4, generated by the agent. - The
consent_scopearray MUST include at least"intake". - The agent SHOULD NOT include PII in
intake_dataunless the manifest'sprivacy.pii_requiredistrue.
Stage 3: Offer
The provider processes the intake and returns a soft-contract offer:
{
"aip_version": "0.1.0",
"session_id": "uuid-v4",
"status": "offer",
"offer": {
"id": "offer-uuid",
"summary": "Human-readable summary for the user.",
"details": { /* structured offer data */ },
"expires": "2026-03-06T00:00:00Z",
"bind_endpoint": "https://provider.com/api/aip/bind",
"bind_requires": ["email", "full_name"]
}
}
Response status codes:
200— Successful response (status may beoffer,declined, orpending).400— Invalid request (malformed JSON, schema mismatch).429— Rate limited.500— Server error.
Response statuses:
| Status | Meaning |
|---|---|
offer | Successful. An offer is included in the response. |
declined | The provider cannot serve this intake. A decline_reason is provided. |
pending | The intake is being processed asynchronously. (Reserved for future use.) |
error | An error occurred. An error object with code and message is provided. |
Stage 4: Review
The review stage is handled entirely by the agent. The protocol does not define message formats for this stage. The agent presents the offer(s) to the user and facilitates decision-making.
Stage 5: Bind
If the user accepts an offer, the agent sends a bind request:
POST {offer.bind_endpoint}
Content-Type: application/json
{
"offer_id": "offer-uuid",
"session_id": "uuid-v4",
"bind_data": {
"email": "user@example.com",
"full_name": "Jane Doe"
},
"agent": {
"id": "agent-instance-id",
"consent_scope": ["intake", "offer", "bind"]
}
}
Requirements:
- The
bind_dataMUST include all fields listed in the offer'sbind_requiresarray. - The
consent_scopeMUST include"bind". - The agent MUST have received explicit user authorization before sending PII.
- The
offer_idandsession_idMUST match the original offer.
JSON Schemas
All schemas use JSON Schema Draft 2020-12. The canonical schema files are in the spec/2026-02-27/ directory.
Manifest Schema: agent-intake.json
The manifest is served at /.well-known/agent-intake.json and describes the provider and available intakes.
Top-level fields
| Field | Type | Required | Description |
|---|---|---|---|
aip_version | string | Yes | Protocol version (semver). |
provider | object | Yes | Provider information. |
intakes | array | Yes | List of available intakes (min 1). |
certification | object | No | Registry certification info. |
Provider object
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Provider's display name. |
url | string (URI) | Yes | Provider's primary URL. |
description | string | No | Brief description of the provider. |
logo | string (URI) | No | URL to provider's logo. |
contact_email | string (email) | No | Contact email for AIP inquiries. |
Intake object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique ID (lowercase, hyphens). Pattern: ^[a-z0-9-]+$ |
name | string | Yes | Human-readable name. |
description | string | Yes | What this intake does. |
endpoint | string (URI) | Yes | URL to POST intake submissions to. |
method | string | Yes | HTTP method. Must be "POST". |
category | string | No | Category (e.g., health/assessment). |
input_schema | object | Yes | JSON Schema for the intake_data payload. |
offer_type | string | Yes | Type of offer returned. |
binding_available | boolean | Yes | Whether binding is supported. |
requires_auth | boolean | No | Whether auth is required. Default: false. |
privacy | object | No | Privacy declarations. |
rate_limit | object | No | Rate limiting info. |
Full example
{
"aip_version": "0.1.0",
"provider": {
"name": "Man vs Health",
"url": "https://manvshealth.com",
"description": "Men's metabolic health optimization"
},
"intakes": [
{
"id": "metabolic-assessment",
"name": "Metabolic Health Assessment",
"description": "Submit metabolic markers for a personalized plan.",
"endpoint": "https://manvshealth.com/api/aip/metabolic-assessment",
"method": "POST",
"category": "health/assessment",
"input_schema": {
"type": "object",
"required": ["age_range", "sex", "primary_concern"],
"properties": {
"age_range": {
"type": "string",
"enum": ["30-39", "40-49", "50-59", "60+"]
},
"sex": {
"type": "string",
"enum": ["male", "female"]
},
"primary_concern": {
"type": "string",
"enum": ["weight", "energy", "insulin_resistance", "general"]
},
"fasting_glucose_range": {
"type": "string",
"enum": ["normal", "elevated", "high", "unknown"]
},
"activity_level": {
"type": "string",
"enum": ["sedentary", "light", "moderate", "active"]
}
}
},
"offer_type": "personalized_recommendation",
"binding_available": true,
"requires_auth": false,
"privacy": {
"data_retention": "none",
"pii_required": false,
"redacted_acceptable": true
}
}
],
"certification": {
"registry": "https://agentintake.io/registry",
"certified": true,
"cert_id": "aip-cert-2026-00142",
"expires": "2027-02-27"
}
}
Intake Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
aip_version | string | Yes | Protocol version. |
agent | object | Yes | Agent info (id, platform, consent_scope). |
intake_data | object | Yes | Data conforming to the intake's input_schema. |
session_id | string (UUID) | Yes | Session identifier for correlation. |
metadata | object | No | Optional metadata (timestamp, locale, timezone). |
Agent object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique agent instance identifier. |
platform | string | No | Agent platform (e.g., "anthropic", "openai"). |
name | string | No | Human-readable agent name. |
consent_scope | array | Yes | Authorized scopes: intake, offer, bind, account_creation, payment. |
Offer Response Schema
| Field | Type | Required | Description |
|---|---|---|---|
aip_version | string | Yes | Protocol version. |
session_id | string (UUID) | Yes | Echoed from the request. |
status | string | Yes | One of: offer, declined, error, pending. |
offer | object | Conditional | Required when status is offer. |
decline_reason | string | No | Present when status is declined. |
error | object | No | Present when status is error. |
metadata | object | No | Optional response metadata. |
Offer object
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique offer identifier. |
summary | string | Yes | Human-readable summary for the user. |
details | object | No | Structured offer details (varies by provider). |
expires | string (date-time) | No | When the offer expires. |
bind_endpoint | string (URI) | No | URL for bind requests. |
bind_requires | array | No | Fields required for binding. |
terms_url | string (URI) | No | Terms and conditions URL. |
Bind Request Schema
| Field | Type | Required | Description |
|---|---|---|---|
offer_id | string | Yes | The accepted offer's ID. |
session_id | string (UUID) | Yes | Session ID from the original intake. |
bind_data | object | Yes | User-authorized PII data. |
agent | object | Yes | Agent info with bind consent. |
metadata | object | No | Optional metadata. |
Common bind_data fields
| Field | Type | Description |
|---|---|---|
email | string (email) | User's email address. |
full_name | string | User's full name. |
phone | string | User's phone number. |
company | string | Company or organization name. |
address | object | Address with street, city, state, postal_code, country. |
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
INVALID_INPUT | 400 | Request body is malformed or missing required fields. |
SCHEMA_MISMATCH | 400 | intake_data does not conform to the declared input_schema. |
RATE_LIMITED | 429 | Too many requests. Retry after the specified period. |
SERVICE_UNAVAILABLE | 503 | The intake service is temporarily unavailable. |
OFFER_EXPIRED | 410 | The referenced offer has expired. |
OFFER_NOT_FOUND | 404 | The referenced offer does not exist. |
BIND_INCOMPLETE | 400 | bind_data is missing required fields. |
INTERNAL_ERROR | 500 | An unexpected error occurred. |
{
"aip_version": "0.1.0",
"session_id": "uuid-v4",
"status": "error",
"error": {
"code": "SCHEMA_MISMATCH",
"message": "Missing required field: age_range"
}
}
Transport Requirements
- Protocol: HTTPS required in production. HTTP allowed for localhost development.
- Content-Type: All requests and responses MUST use
application/json. - CORS: Providers SHOULD set
Access-Control-Allow-Origin: *and handleOPTIONSpreflight requests. - Encoding: UTF-8.
- Request size: Providers SHOULD accept request bodies up to 64 KB.
- Response time: Providers SHOULD respond within 10 seconds. For longer processing, use
status: "pending".
Standard Categories
Categories follow the pattern {domain}/{type}:
| Category | Description | Example |
|---|---|---|
health/assessment | Health evaluations and screenings | Metabolic assessment |
service/matching | Service provider marketplaces | Find a plumber |
saas/onboarding | SaaS trial and setup | Project management trial |
finance/quote | Financial quotes and estimates | Insurance quote |
tool/calculator | Stateless calculations | BMI calculator |
b2b/vendor | B2B vendor evaluation | Cloud hosting proposal |
education/course | Educational programs | Curriculum recommendation |
Providers MAY use custom categories following the same {domain}/{type} pattern.
Versioning
- Semantic versioning: The
aip_versionfield uses semver (e.g.,0.1.0). - Date snapshots: Schema files are organized by date (e.g.,
spec/2026-02-27/). - Breaking changes increment the minor version and create a new date directory.
- Agents SHOULD check the
aip_versionin manifests and responses to ensure compatibility. - Providers SHOULD include
aip_versionin all responses.
Security Considerations
- HTTPS: All production endpoints MUST use HTTPS.
- Input validation: Providers MUST validate intake_data against their declared input_schema.
- Rate limiting: Providers SHOULD implement rate limiting and declare limits in the manifest.
- PII handling: PII received during binding MUST be handled in accordance with applicable privacy regulations.
- Offer expiration: Providers SHOULD enforce offer expiration to prevent stale bindings.
- Agent verification: The current spec does not mandate agent authentication. Future versions may integrate with identity protocols like AGNTCY.