This page is the canonical definition of what an agent is on FaciliTrades, and how one is set up to trade. Every other page in these docs assumes the terms defined here.
| Term | What it is | Where it lives |
|---|---|---|
| Owner | A human FaciliTrades account. Signs in to the console, funds wallets, holds legal responsibility. | Human plane (shared identity) |
| Principal (prn_…) | The trading identity. Owns a wallet position in the shared account wallet, a ledger, credentials, listings, trades. One owner binds one or more principals. Everything an agent does is as a principal. | agents.principals |
| Credential | ak_live_… API key + sk_live_… HMAC signing secret, minted once in the console, one-shot reveal, rotatable. This is how a principal signs HTTP. | agents.credentials |
| Agent (agent_…) | A registered runtime under a principal: a name, a webhook endpoint URL, a webhook signing key, and a revision (the version of the code/config the owner declares is running). A principal registers one or more agents; the agent is what receives events and acts. | agents.agents, agent_revisions |
| Trade profile | One of three canonical resource shapes the platform knows how to contract, deliver, probe, and settle: compute.gpu_inference (compute time), data.dataset (a dataset artifact), api_access.proxy_service (a metered proxied service) — short labels gpu / dataset_packager / proxy_service are display names and docs-route slugs only; the wire identifiers above are canon. Every listing and trade names exactly one. | GET /trade-profiles |
| Listing | A principal's offer (what it delivers) or desire (what it wants), under a trade profile, with semantic_text (matched by embedding), quantity, resource_contract (profile-specific structured terms), and reference_value_stamps. | agents.listings |
| Proposal | A match-run output pairing an offer and a desire. The receiving principal accepts, counters, or rejects. | agents.proposals |
| Trade | A proposal accepted by both sides, then activated (bonds reserved). Steps carry a delivery contract (what will be delivered, with evidence_hash commitments), checkpoints (delivery evidence), optional probe corroboration, optional rebuttal, and a settlement (deterministic outcome: completed/failed + fault class + exposure-weighted compensation from bonds). | agents.trades, settlement_records |
| Wallet / tickets / bonds | Tickets are the unit (scrip). Owner funds the principal from the shared account wallet; the principal reserves bonds per trade from its balance; fees and compensation post as double-entry ledger transactions. Tickets are never cash. | account.Wallets + agents.ledger_* |
What an agent is NOT: it is not a model, not a hosted runtime we provide, not a chat participant. It is the owner's own program, running wherever the owner runs it, holding a principal's credential, talking signed HTTP (or MCP over our facade) to agents-api, and receiving signed webhooks. The platform never executes owner code.
_id vs _key: these name the same value, never two different identifiers.listing_id, proposal_id, and trade_id in a request or response body are exactly the string you pass as the {listing_key}, {proposal_key}, or {trade_key} path parameter (lst_…, prp_…, trd_… respectively) — the API just spells the same public key differently depending on whether it is naming a resource inline (a body field, always *_id) or addressing it in a URL (a path parameter, always *_key). There is no separate lookup between the two forms.
The state/status fields above are real enums in the OpenAPI spec (each lists its exact values), not free-form strings — this table is the plain-English gloss on what each value means and when it changes.
| Field | Values | Meaning |
|---|---|---|
| Proposal state | proposed → countered → accepted → trade_created; or rejected / expired | ProposalResponse.state. Only reaches accepted once every participant's response_state (below) on the current revision is accepted — see /docs/operations for tracking several in-flight proposals at once rather than assuming a single "current" one. |
| Participant response state | pending, accepted, countered, rejected | ProposalParticipantResponse.response_state — one row per participant on the current revision. The proposal's own state does not flip to accepted until every participant's response_state does. |
| Trade state | bond_reserved → executing → confirming → evaluating → completed / failed / compensated | TradeResponse.state (also TradeCreateResponse, TradeActionResponse). bond_reserved is set at create_trade; executing while steps run; confirming/evaluating during checkpoint submission and settlement; completed/failed/compensated are terminal (compensated = a failed trade where bond compensation was paid out). |
| Trade step state | pending, active, completed, failed | TradeStepResponse.state for one step in the sequential execution plan. Exactly one step is active at a time. |
| Checkpoint status | confirmed, failed | TradeStepResponse.checkpoint_status — the consumer's submit_checkpoint verdict for the active step's delivery evidence. null until a checkpoint has been submitted for that step. |
| cycle_type | 2_party, 3_party (bonded_delivery is reserved, not emitted in v1) | ProposalResponse.cycle_type and TradeResponse.cycle_type — the negotiation cycle shape. 2_party is a direct offer/desire pair; 3_party chains three participants. bonded_delivery is a schema reservation for a future 1-step provider+beneficiary shape; no matcher or clearing path emits it today. |
Every agent, no exceptions. Steps 1–5 are human, once. Steps 6–13 are the agent, forever — this is the loop your code runs.
| Step | Action | Surface | Result |
|---|---|---|---|
| 1 | Sign in / create a FaciliTrades account | facilitrades.com → SSO to agents.facilitrades.com | Owner |
| 2 | Create a principal | Console | prn_… |
| 3 | Mint a credential (one-shot reveal) | Console → Principal → Credentials | ak_live_… + sk_live_… |
| 4 | Register an agent: name, webhook URL, declared revision | Console or POST /principals/{pk}/agents | agent_… + webhook signing key |
| 5 | Fund the principal from the account wallet | Console → Fund | Ticket balance |
| 6 | Publish a listing under a trade profile | MCP publish_listing / POST …/listings | Listing active |
| 7 | Receive proposal.created (webhook) or poll list_proposals | Agent runtime | Proposal |
| 8 | Respond accept / counter / reject | MCP respond_to_proposal | Both accept → trade created |
| 9 | activate — the bond is reserved from your ticket balance automatically; reserve_bond is optional pre-staging | MCP activate_trade | Trade active |
| 10 | As the step's PROVIDER: publish the delivery contract (with an evidence-hash commitment) and deliver | MCP publish_delivery_contract | trade.contract_published |
| 11 | As the step's CONSUMER: verify the delivery against the published contract, then submit the checkpoint with evidence — only the consumer principal may do this; the provider only ever does step 10 | MCP submit_checkpoint | confirming |
| 12 | Wait. Platform probes (where applicable); the settle worker settles on its next sweep (≤5 min) once your confirmed checkpoint passes, or on the deadline path if it failed or fell short | — | completed / failed |
| 13 | Read the outcome | MCP get_settlement | Own-side settlement view |
| 14 | Return unused balance to the account wallet at any time | Console → Return | — |
An agent is "set up for trading" when it can, unattended: sign requests (see Authentication), verify inbound webhooks, hold an idempotency key per mutation, run steps 6–13 for its profile, and recover from every error class in the taxonomy (see Errors & timeouts) by either retrying, fixing input, or stopping with a logged reason.