Skip to content
ApiqDevelopers
API v1.64.0Open console

Submit agent proposal

POST/v1/agent-proposals
Idempotency-Key requiredAccepts X-Api-Key · oauthClientCredentials · bearer

An agent submits an L1 proposal — the uniform reviewable envelope

Called by an AGENT service principal — an API key or a POST /v1/oauth/token service token holding agents:propose.Show moreCalled by an AGENT service principal — an API key or a POST /v1/oauth/token service token holding agents:propose. The platform stamps actor {kind: ai, agentId} from that credential; the body's agentId must be the credential's agent, otherwise 403 PERMISSION_DENIED details.reason AGENT_MISMATCH. A system key or a human session filing is 403 PERMISSION_DENIED details.reason AGENT_CREDENTIAL_REQUIRED: a system key can never file a proposal or act as the AI plane. Actor kind is bound to the credential, never to a request header. A paused agent is 409 CONFLICT details.reason AGENT_PAUSED. The proposal is OPEN until a human approves or rejects it or it expires; nothing is executed at submission. Emits agent.proposal.created.

Headers

  • Idempotency-KeystringRequired
    Mandatory on mutations: **48h TTL**; replay with same body-hash returns the original response with Idempotency-Replayed true; same key + different body is 409 IDEMPOTENCY_CONFLICT; in-flight duplicate…Show moreMandatory on mutations: **48h TTL**; replay with same body-hash returns the original response with Idempotency-Replayed true; same key + different body is 409 IDEMPOTENCY_CONFLICT; in-flight duplicate is 409 IDEMPOTENCY_IN_PROGRESS.

Request body

  • agentIdstringRequired
    Must be the agent the credential belongs to (403 PERMISSION_DENIED AGENT_MISMATCH otherwise)
  • typestringRequired
    Open string — REBOOKING (AG-22), ADOPTION_BRIEF (AG-24), RECONCILIATION (AG-13), CONFIG_CHANGE
  • titlestringRequired
  • summarystringRequired
    Shown to the approver as data; amounts are rendered from `amount`, never from this text
  • resourceConsoleResourceRefRequired
    2 child attributes
    • typestringRequired
      Open string — order | credential_set | ruleset | webhook | user | invite | agent-proposal | branding
    • refstringRequired
  • requiresApprovalTokenbooleanRequired
    True for every money-touching or irreversible proposal.Show moreTrue for every money-touching or irreversible proposal. The PLATFORM decides the stored value from the proposal's type, its changes and its approvalAction, never from this field alone: a proposal the platform classes as money-touching is stored true whatever is sent, and one submitted with false is refused 400 VALIDATION details.field requiresApprovalToken. The submitted value can only raise the flag, never lower it
  • approvalActionstringOptional
    Required whenever the proposal moves money: a money-touching proposal (by type, changes or requiresApprovalToken) without it is 400 VALIDATION details.field approvalAction.Show moreRequired whenever the proposal moves money: a money-touching proposal (by type, changes or requiresApprovalToken) without it is 400 VALIDATION details.field approvalAction. The grant's resourceRef is resource.ref and its amount is `amount`. payments.* is a valid grant action but is not executable by a proposal: a money proposal whose approvalAction is payments.* is 400 VALIDATION details.reason ACTION_NOT_EXECUTABLE; amend.commit is 400 AMEND_COMMIT_NOT_EXECUTABLE. Only orders.create and orders.cancel are accepted
  • amountMoneyOptional
    Integer minor units + ISO-4217, never floats (platform law)
    5 child attributes
    • amountintegerRequired
      Minor units
    • currencystringRequired
      ISO-4217
    • fxAppliedbooleanOptional
      True when the amount was converted from the supplier's currency.
    • fxSnapshotIdstringOptional
      The exchange-rate snapshot the amount was converted with, fixed when the price was quoted.
    • breakdownarray of PriceBreakdownLineOptional
      Sell-side component lines summing to amount; the platform may send it empty.Show moreSell-side component lines summing to amount; the platform may send it empty. One line shape everywhere — the same PriceBreakdownLine the rule simulation answers. Never carries a supplier net.
      13 child attributes
      • typestringRequired
        The kind of line, for example BASE, TAX, FEE or DISCOUNT.
      • amountintegerRequired
        Minor units
      • feeTypestringOptional
        For FEE lines produced by a FEE_LINE rule — the tenant's fee label
      • labelstringOptional
        Display label in the request locale
      • taxComponentstringOptional
        For GST / TAX lines — CGST | SGST | IGST | UTGST | CESS | VAT | SALES_TAX | OCCUPANCY_TAX; open string
      • taxCodeTaxCodeOptional
        The statutory classification of a taxed line (SAC/HSN in India, VAT codes elsewhere)
        2 child attributes
        • schemestringRequired
          SAC | HSN | VAT | GST | OTHER; open string
        • codestringRequired
          The tax code, for example a SAC or HSN code in India or a VAT code elsewhere.
      • rateBasisPointsintegerOptional
        The tax or fee rate in basis points when the line is rate-based (1800 = 18%)
      • collectedBystringOptional
        PLATFORM | SUPPLIER | PROPERTY — who takes the money; a non-PLATFORM line outside Offer.price is a pay-at-property disclosure
      • payableAtstringOptional
        BOOKING | PROPERTY | DESK | AFTER_SERVICE
      • includedbooleanOptional
        True when the line is inside the enclosing amount (default); false for a disclosed line outside it
      • quantityintegerOptional
        How many units the line covers, when more than one.
      • unitAmountintegerOptional
        Minor units per unit when quantity is given
      • currencystringOptional
        ISO-4217 code of this line's amount and unitAmount.Show moreISO-4217 code of this line's amount and unitAmount. Set ONLY on a disclosed line (included false) that is NOT in the enclosing price's currency, for example a resort fee payable at the property in its local currency. Absent means the enclosing price's currency, as before; a line inside the total never carries it.
  • evidencearray of ConsoleEvidenceRefRequired
    3 child attributes
    • kindstringRequired
      • TRACE
      • ORDER
      • EVENT
      • CAPTURE
      • DOCUMENT
      • URL
    • refstringRequired
    • labelstringOptional
  • changesarray of ConsoleProposedChangeRequired
    3 child attributes
    • pathstringRequired
    • beforestringOptional
    • afterstringOptional
  • projectedEffectConsoleProjectedEffectOptional
    What executing the proposal does; money as Money
    2 child attributes
    • descriptionstringRequired
    • amountDeltaMoneyOptional
      Integer minor units + ISO-4217, never floats (platform law)
      5 child attributes
      • amountintegerRequired
        Minor units
      • currencystringRequired
        ISO-4217
      • fxAppliedbooleanOptional
        True when the amount was converted from the supplier's currency.
      • fxSnapshotIdstringOptional
        The exchange-rate snapshot the amount was converted with, fixed when the price was quoted.
      • breakdownarray of PriceBreakdownLineOptional
        Sell-side component lines summing to amount; the platform may send it empty.Show moreSell-side component lines summing to amount; the platform may send it empty. One line shape everywhere — the same PriceBreakdownLine the rule simulation answers. Never carries a supplier net.
        13 child attributes
        • typestringRequired
          The kind of line, for example BASE, TAX, FEE or DISCOUNT.
        • amountintegerRequired
          Minor units
        • feeTypestringOptional
          For FEE lines produced by a FEE_LINE rule — the tenant's fee label
        • labelstringOptional
          Display label in the request locale
        • taxComponentstringOptional
          For GST / TAX lines — CGST | SGST | IGST | UTGST | CESS | VAT | SALES_TAX | OCCUPANCY_TAX; open string
        • taxCodeTaxCodeOptional
          The statutory classification of a taxed line (SAC/HSN in India, VAT codes elsewhere)
        • rateBasisPointsintegerOptional
          The tax or fee rate in basis points when the line is rate-based (1800 = 18%)
        • collectedBystringOptional
          PLATFORM | SUPPLIER | PROPERTY — who takes the money; a non-PLATFORM line outside Offer.price is a pay-at-property disclosure
        • payableAtstringOptional
          BOOKING | PROPERTY | DESK | AFTER_SERVICE
        • includedbooleanOptional
          True when the line is inside the enclosing amount (default); false for a disclosed line outside it
        • quantityintegerOptional
          How many units the line covers, when more than one.
        • unitAmountintegerOptional
          Minor units per unit when quantity is given
        • currencystringOptional
          ISO-4217 code of this line's amount and unitAmount.Show moreISO-4217 code of this line's amount and unitAmount. Set ONLY on a disclosed line (included false) that is NOT in the enclosing price's currency, for example a resort fee payable at the property in its local currency. Absent means the enclosing price's currency, as before; a line inside the total never carries it.
  • undoPlanstringOptional
  • expiresAtstring · date-timeOptional
    Optional, earlier than the default; absent = 48h after submission, and never later than the idempotency window
  • executionAgentProposalExecutionOptional
    What approve runs. Required when the proposal is money-touching (requiresApprovalToken true): a money proposal without it is 400 VALIDATION details.field execution.Show moreWhat approve runs. Required when the proposal is money-touching (requiresApprovalToken true): a money proposal without it is 400 VALIDATION details.field execution. execution.action must equal approvalAction and execution.currency must equal amount.currency, else 400 VALIDATION details.reason EXECUTION_INCONSISTENT. Never echoed back; the outcome is the proposal's `executionResult`.
    4 child attributes
    • actionstringRequired
      • orders.create
      • orders.cancel
      • amend.commit
    • domainstringRequired
      The travel domain the verb runs in (flights, hotels, …)
    • currencystringRequired
      ISO 4217 currency of the verb's money; must equal the proposal's amount.currency
    • intentobjectRequired
      The verb's message.intent exactly as POST /v1/orders, the cancel or the amend call takes it

Responses

  • 201Stored OPEN; nothing executedConsoleAgentProposal
  • 400
    A money proposal without `execution` is 400 VALIDATION details.field execution.Show moreA money proposal without `execution` is 400 VALIDATION details.field execution. details.reason AMEND_COMMIT_NOT_EXECUTABLE: an amend.commit proposal (approvalAction or execution.action) is refused at submit until quote-then-commit exists; amend.commit stays in the action enums on purpose so this refusal is reachable. details.reason ACTION_NOT_EXECUTABLE: a money proposal whose approvalAction is payments.* (confirm, capture, void, refund) is refused at submit; only the order verbs execute. details.reason EXECUTION_INCONSISTENT: execution.action differs from approvalAction, or execution.currency differs from amount.currency (details.field names which). An orders.cancel execution.intent must carry acceptedPenalty equal to the proposal's amount.
    ApiErrorResponse
  • 401
    UNAUTHENTICATED — missing or expired token.Show moreUNAUTHENTICATED — missing or expired token. Declared on every operation because `security` is declared globally at the document root: every route is authenticated, so every route can answer 401.
    ApiErrorResponse
  • 403
    PERMISSION_DENIED: the credential lacks agents:propose; the body's agentId is not the credential's agent (details.reason AGENT_MISMATCH); or the caller is not an agent credential at all, a system key…Show morePERMISSION_DENIED: the credential lacks agents:propose; the body's agentId is not the credential's agent (details.reason AGENT_MISMATCH); or the caller is not an agent credential at all, a system key or a human session. TENANT_MISMATCH, TAB_DISABLED and OUT_OF_SCOPE as on every route.
    ApiErrorResponse
  • 405
    VALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge).Show moreVALIDATION — the public edge serves GET, POST, PUT, PATCH and DELETE only; any other method is refused before the platform sees it (details.reason METHOD_NOT_ALLOWED, details.source edge). Not retryable as sent.
    ApiErrorResponse
  • 409CONFLICT details.reason AGENT_PAUSED | IDEMPOTENCY_CONFLICT | IDEMPOTENCY_IN_PROGRESSApiErrorResponse
  • 413
    VALIDATION — the request body is larger than the surface's limit.Show moreVALIDATION — the request body is larger than the surface's limit. Not retryable as sent: shrink the body. Declared on every operation that takes a request body. details carries exactly one key, maxBodyBytes (integer): the limit that applies to this surface, in bytes.
    ApiErrorResponse
  • 414
    VALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge).Show moreVALIDATION — the request URI (path and query string) is longer than 8 KiB; the public edge refuses it before the platform sees it (details.reason URI_TOO_LONG, details.source edge). Not retryable as sent: send long input in the body of a POST.
    ApiErrorResponse
  • 415
    VALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes).Show moreVALIDATION — a request body that is not JSON (application/json or application/*+json; a form body only on the OAuth token routes). The public edge refuses it before the platform sees it (details.reason UNSUPPORTED_MEDIA_TYPE, details.source edge). Not retryable as sent: send Content-Type application/json. Declared on every operation that takes a JSON request body.
    ApiErrorResponse
  • 429
    RATE_LIMITED — the API key or its tenant is over a rate limit; wait for Retry-After, then retry.Show moreRATE_LIMITED — the API key or its tenant is over a rate limit; wait for Retry-After, then retry. Every routed request is counted against two token buckets, the key's and the tenant's (all its keys together): 50 requests a second with a burst of 100 on the standard plan. Every travel verb except polling a search also spends from a supplier budget, per key and per tenant: 10 requests a second with a burst of 20, and a plan may add a daily quota of supplier calls. Answers carry the IETF RateLimit header fields for the tightest bucket consulted (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, RateLimit-Policy); a refusal adds Retry-After and details.scope (KEY or TENANT), details.budget (PLATFORM or SUPPLIER), details.reason (RATE or DAILY_QUOTA), details.tier and details.retryAfterMs. A sandbox may run with the limiter off, in which case none of these headers is sent. A search that is still warming is a different answer with a different meaning (keep polling). with the key-velocity check on, also details.reason VELOCITY_LIMIT, a soft breach of the API key's own scope (components/responses/VelocityLimited), nextAction slow_down.
    ApiErrorResponse
  • 500INTERNAL — a bug, and traceId is the support handle.ApiErrorResponse

Errors you should handle

Branch on code and honour retryable — never on the HTTP status alone.

400VALIDATION
A REBOOKING proposal moves money and must name approvalAction.
not retryable
401UNAUTHENTICATED
The bearer token is expired. Re-authenticate and retry.
not retryable
403PERMISSION_DENIED
Only an agent credential files a proposal; a system key or a human session cannot.
not retryable
403TAB_DISABLED
Tenant acme-travel is not entitled to sell CRU
not retryable
403OUT_OF_SCOPE
The token's scope ladder does not reach this customer subtree
not retryable
403TENANT_MISMATCH
orderRef MO-8KD-2FQ-9XT does not belong to tenant acme-travel
not retryable
405VALIDATION
This method is not served.
not retryable
409CONFLICT
Agent agt_rebook_22 is paused and cannot submit proposals.
not retryable
409IDEMPOTENCY_CONFLICT
Idempotency-Key 7f0c33d1-9a1e-4d2c-9f77-1c0f2b3a4d55 was used with a different body; never executed
not retryable
409IDEMPOTENCY_IN_PROGRESS
A request with this Idempotency-Key is still executing
retryable
413VALIDATION
The request body is larger than this API accepts (262144 bytes).
not retryable
414VALIDATION
The request URI is longer than 8 KiB.
not retryable
415VALIDATION
Send application/json.
not retryable
429RATE_LIMITED
Too many requests for this key on the supplier budget. Wait for the Retry-After interval before trying again.
retryable
500INTERNAL
An unexpected error occurred. Quote the traceId to support.
retryable