API Reference
Base URL: https://api.dockai.co
| Endpoint | Auth | Rate Limit |
|---|---|---|
| GET /v1/resolve/domain/:domain | None | 100/min |
| POST /v1/submit | None | 10/min |
| POST /v1/providers/sync | API Key / JWT | 100/min |
| POST /v1/providers/register | API Key | 200/min |
GET /v1/resolve/domain/:domain
Resolve a domain to its MCP endpoints. Returns all entities associated with the domain and their available MCP providers.
Parameters
| Name | Type | Description |
|---|---|---|
| domain | path | The domain to resolve (e.g., example-restaurant.com) |
| path | query | Optional. Filter to a specific entity path (e.g., /paris) |
Response
// 200 OK
{
"domain": "example-restaurant.com",
"entities": [
{
"name": "Example Restaurant Paris",
"path": "/paris",
"location": {
"city": "Paris",
"country": "FR",
"coordinates": { "lat": 48.8566, "lng": 2.3522 }
},
"verification_level": 2,
"mcps": [
{
"provider": "sevenrooms",
"endpoint": "https://mcp.sevenrooms.com",
"entity_id": "rest-123",
"capabilities": ["reservations", "availability"],
"verification": {
"level": 2,
"method": "dual_attestation"
}
}
],
"pending_providers": [
{
"provider_domain": "thefork.com",
"provider": "thefork",
"capabilities": ["reservations"]
}
]
}
]
}Response Fields
| Field | Type | Description |
|---|---|---|
| entities[].mcps | array | Active MCP endpoints for this entity |
| entities[].pending_providers | array | Providers detected but not registered with Dock AI |
| mcps[].entity_id | string | Entity's identifier at the provider (use when calling MCP) |
| mcps[].verification.level | number | 0 = provider claim, 1 = entity claim, 2 = dual attestation |
Errors
// 404 Not Found
{
"error": "Entity not found",
"domain": "unknown-domain.com"
}
// 429 Too Many Requests
{
"error": "Rate limit exceeded. Try again in 60 seconds."
}
// 500 Internal Server Error
{
"error": "Internal server error"
}POST /v1/submit
Submit a domain to crawl its Entity Card. Dock AI will fetch the Entity Card from/.well-known/entity-card.json and index the entities.
Request
POST /v1/submit
Content-Type: application/json
{
"domain": "example-restaurant.com"
}Response
// 200 OK
{
"success": true,
"domain": "example-restaurant.com",
"entity": {
"id": "uuid",
"name": "Example Restaurant",
"verification_level": 1
},
"mcps_count": 2
}
// 200 OK (already indexed)
{
"success": true,
"domain": "example-restaurant.com",
"entity": {
"id": "uuid",
"name": "Example Restaurant",
"verification_level": 2
},
"mcps_count": 2,
"message": "Entity already indexed, updated"
}Errors
// 400 Bad Request
{
"error": "Invalid request",
"details": { "domain": ["Required"] }
}
// 400 Bad Request (no entity card)
{
"error": "No entity card found at https://example.com/.well-known/entity-card.json"
}
// 400 Bad Request (domain mismatch)
{
"error": "Domain mismatch: card declares \"other.com\" but hosted on \"example.com\""
}
// 429 Too Many Requests
{
"error": "Rate limit exceeded. Try again in 60 seconds."
}POST /v1/providers/sync
Recommended. Full sync API - send all your entities, we handle the diff. Entities not in the request are automatically deleted.
≤1,000 entities: Synchronous processing
>1,000 entities: Async background job (poll for status)
No limit on entity count. Import 50K+ in one request.
Authentication
Two authentication methods are supported:
# Option 1: API Key (for external integrations)
Authorization: Bearer sk_live_xxxxx
# Option 2: Supabase JWT (from dashboard)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...Request
POST /v1/providers/sync
Authorization: Bearer sk_live_xxxxx
Content-Type: application/json
{
"entities": [
{
"entity_id": "venue-123",
"name": "Example Restaurant Paris",
"domain": "example-restaurant.com",
"path": "/paris",
"category": "restaurant",
"city": "Paris",
"country": "FR",
"lat": 48.8566,
"lng": 2.3522,
"capabilities": ["reservations", "availability"]
},
{
"entity_id": "venue-456",
"name": "Example Restaurant Lyon",
"city": "Lyon",
"country": "FR"
}
]
}Entity Fields
| Field | Required | Description |
|---|---|---|
| entity_id | Yes | Your internal identifier |
| name | Yes | Display name |
| domain | No | Entity's website domain |
| path | No | Path within domain (e.g., /paris) |
| category | No | Entity category |
| city, country | No | Location info |
| lat, lng | No | GPS coordinates |
| capabilities | No | What your MCP can do |
Response
// Synchronous (≤1,000 entities)
{
"success": true,
"async": false,
"provider": "sevenrooms",
"results": {
"total": 500,
"created": 100,
"updated": 350,
"deleted": 50,
"unchanged": 0,
"errors": 0
}
}
// Asynchronous (>1,000 entities)
{
"async": true,
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "pending",
"total_entities": 50000,
"message": "Processing 50,000 entities in background..."
}Polling Job Status
For async jobs, poll GET /v1/providers/sync?job_id=... until complete:
{
"job_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing", // pending | processing | completed | failed
"total_entities": 50000,
"processed_entities": 25000,
"created": 5000,
"updated": 20000,
"deleted": 100,
"errors": 0
}Full Sync Behavior: Entities not included in the request are automatically deleted. This ensures your registry stays in sync with your database.
POST /v1/providers/register
Operations-based API for granular control. Use /v1/providers/sync for simpler integration. Supports upsert and delete operations (up to 1000 per request).
Authentication
Authorization: Bearer sk_live_xxxxxAPI keys are issued after provider verification. Contact us to register as a provider.
Request
POST /v1/providers/register
Authorization: Bearer sk_live_xxxxx
Content-Type: application/json
{
"operations": [
{
"action": "upsert",
"entity": {
"entity_id": "venue-123",
"domain": "example-restaurant.com",
"path": "/paris",
"name": "Example Restaurant Paris",
"category": "restaurant",
"location": {
"city": "Paris",
"country": "FR",
"coordinates": { "lat": 48.8566, "lng": 2.3522 }
},
"capabilities": ["reservations", "availability"]
}
},
{
"action": "delete",
"entity_id": "old-venue-456"
}
]
}Operations
| Action | Description |
|---|---|
| upsert | Create or update an entity. If domain matches existing entities, links to them. |
| delete | Remove an entity by entity_id. Only removes your MCP endpoint, not the entity itself. |
Entity Fields
| Field | Required | Description |
|---|---|---|
| entity_id | Yes | Your internal identifier for this entity |
| name | Yes | Display name of the entity |
| domain | No | Entity's website domain. If omitted, creates provider-only entity. |
| path | No | Path within domain (e.g., /paris). If omitted with domain, matches all entities. |
| category | No | Entity category (e.g., restaurant, hotel) |
| location | No | Geographic location (city, country, coordinates) |
| capabilities | No | What your MCP can do (e.g., reservations, ordering) |
Response
// 200 OK
{
"success": true,
"provider": "sevenrooms",
"results": {
"total": 2,
"created": 1,
"updated": 0,
"deleted": 1,
"errors": 0
}
}
// 200 OK (with errors)
{
"success": false,
"provider": "sevenrooms",
"results": {
"total": 3,
"created": 1,
"updated": 1,
"deleted": 0,
"errors": 1
},
"errors": [
{
"entity_id": "bad-venue",
"error": "Invalid location coordinates"
}
]
}Errors
// 401 Unauthorized
{
"error": "Missing or invalid Authorization header. Use: Bearer <api_key>"
}
// 401 Unauthorized
{
"error": "Invalid API key or provider not verified"
}
// 400 Bad Request
{
"error": "Invalid request",
"details": { "operations": ["Required"] }
}
// 429 Too Many Requests
{
"error": "Rate limit exceeded. Try again in 60 seconds."
}Standard Capabilities
Capabilities describe what actions are possible via an MCP. Use these standard values for interoperability.
| Category | Capabilities |
|---|---|
| Booking | reservations, availability, cancellation |
| Commerce | ordering, payments, catalog |
| Information | menu, hours, contact |
| Communication | messaging, notifications |
Custom capabilities can use namespaced format: provider:capability