Capabilities
The capability profile is the contract between your systems and the platform's orchestrator: it declares what your connection can do, and the platform never calls what the profile does not advertise. Start integration here; everything else routes on it. Full shape: capability_profile.
At a glance
- Scope:
catalog:write - Declares: transports, capabilities, rate cadence, SLAs; the seller level is computed from them
- Changing a declaration flips capability live: no contract change, no redeploy
Read your profile
GET/v1/me/capabilitiescatalog:write
Returns the profile the orchestrator currently routes on: the source of truth for what the platform will and will not call.
Response
The full capability_profile object.
200 Response
{
"seller_id": "acme",
"conformance_level": 2,
"transports": {
"result_delivery": ["callback", "poll", "console"],
"formats": ["json", "csv", "xlsx"]
},
"capabilities": {
"realtime_availability": true,
"counter_proposals": false,
"reservation_hold": false
},
"rate_management": {
"rates": "frozen_quarterly"
},
"sla": {
"standard": {
"min_lead_minutes": 2880,
"max_decision_latency_minutes": 240
}
}
}
Update your profile
PUT/v1/me/capabilitiescatalog:write
Replaces the profile. Declare only what your systems actually serve; the orchestrator degrades gracefully around anything absent, and a declared-but-null capability can flip live later without a contract change.
conformance_level is not part of the write. The level is what your declarations add up to, so the platform computes it from them and emits it on every read (and to buyers as level on GET /v1/sellers); a level sent here is ignored rather than validated, so a profile can never claim a level its declarations do not support. Levels are cumulative, but each capability's direction is free: push avails by file while orders pull into your endpoint. See Seller levels.
The derivation is this decision table and nothing else. Each rung has one declared marker; a missing field reads as its default (false, and an undeclared rate_management.rates reads as undeclared). The level is the highest rung whose marker and every marker below it hold, so the published level is cumulative by construction whatever the profile declares:
| Rung | Holds when |
|---|---|
| 1 | rate_management.rates is declared, any value: the seller distributes a rate card on some cadence. |
| 2 | capabilities.realtime_availability is true. |
| 3 | capabilities.counter_proposals is true. |
| 4 | capabilities.reservation_hold is true. The rung's fuller description (sync decisions, clearance pricing) has no separate declarations today; this is its one declared marker. |
Level 0 when rung 1 fails. A non-cumulative combination is a legal profile, never a 422: reservation_hold: true with counter_proposals: false computes the level of the unbroken prefix (here Level 2, given rungs 1 and 2 hold) and the hold capability still routes, because the orchestrator and every feature gate read the individual declarations, never the summary. The level is a buyer-facing summary of the unbroken ladder, nothing more; boundary cases for every rung belong in the conformance tests.
Request body
| Field | Type | Description |
|---|---|---|
transports.result_delivery required | array of string | Decision delivery rungs you offer: callback, poll, sqs, console. |
transports.formats | array of string | File formats you accept and produce: json, csv, parquet, xlsx. |
capabilities.realtime_availability | boolean | Whether avails are live or on a declared cadence. Default: false. |
capabilities.counter_proposals | boolean | Whether decide may counter, per unit. Default: false. |
capabilities.reservation_hold | boolean | Level 4 holds with TTL. Default: false. |
rate_management.rates | enum | frozen_quarterly or live: how your rate cards move. Availability movement is capabilities.realtime_availability alone: the two facts are orthogonal and no longer share one enum. There is no pricing_modes list to maintain: how a product prices is its per-product disclosure.pricing_policy, and a seller-level restatement in a second vocabulary (with no value for quote at all) was removed rather than derived. |
sla | object | Per service class: min_lead_minutes (shortest lead you accept) and max_decision_latency_minutes (how long a decision may take before the platform chases it). One unit, minutes, on both figures: two durations in two units inside one object is the shape of a real incident. |
Example request
{
"transports": {
"result_delivery": ["callback", "poll", "console"],
"formats": ["json", "csv", "xlsx"]
},
"capabilities": {
"realtime_availability": true,
"counter_proposals": false,
"reservation_hold": false
},
"rate_management": {
"rates": "frozen_quarterly"
},
"sla": {
"standard": {
"min_lead_minutes": 2880,
"max_decision_latency_minutes": 240
}
}
}
Response
200 Response
{
"seller_id": "acme",
"conformance_level": 2,
"updated_at": "2026-10-01T12:00:00Z"
}
Errors
| Status | Code | When |
|---|---|---|
| 422 | INVALID_INPUT | Unknown transport or mode. There is no "level inconsistent with the declared capabilities" error left to make: the level is computed from the declarations, never accepted. |
Error shape and recovery: Errors.