Docs
⌕ ⌘K
Resources / Changelog

Changelog

Changes to the Nustro API, dashboard, and these guides. Breaking changes are announced before they ship and are never applied silently.

What counts as breaking

Build against this contract and additive changes will not disturb you.

ChangeBreaking?Notes
New endpointNoIgnore what you do not use.
New optional request fieldNoDefaults preserve existing behaviour.
New response fieldNoYour parser must tolerate unknown fields. This is the most common source of self-inflicted breakage.
New enum valueNoHandle unrecognised values as a default case rather than failing.
New event typeNoIgnore event types you do not recognise.
New error codeNoFall back on the HTTP status class.
Removing or renaming a fieldYesAnnounced, with a migration window.
Changing a field’s type or meaningYesAnnounced. Semantics changes are treated as seriously as type changes.
Removing an event type or error codeYesAnnounced.
Tightening validationYesA request that used to succeed and now fails is breaking, even if it was always ill-formed.
Nustro enforces

Additive changes ship without notice, so your integration must tolerate them: unknown fields, unknown enum values, unknown event types, unknown error codes. A parser that rejects what it does not recognise will break on a change that broke nobody else.

How changes are announced

ChannelCarries
This pageEverything, newest first
customer.* noticesAccount-affecting changes, to your registered admin contact
Status pageIncidents and degradations — operational, not contractual

Sandbox receives changes ahead of production wherever the difference is meaningful, so an integration tested there sees new behaviour before its live traffic does.

Log

2026-10-21 Breaking
Disputes are signed by the agents, with pre-arbitration and board hearings
  • POST /v1/disputes replaces POST /v1/agents/{did}/transactions/{transaction_id}/disputes. Filing is signed by the buyer agent’s certificate and proof; a platform key or dashboard session gets 401 agent_credential_required. The platform relay and filed_via are gone — a principal acts through your app, which signs as the agent.
  • Body: transaction_id, disputed_amount, currency, reason, resolution_sought, description. Evidence moves to POST /v1/disputes/{dispute_id}/evidence. Only the buyer can file, and only up to the unrefunded value.
  • Pre-arbitration: the seller can concede or make an offer; the buyer can offer/accept or offer/reject. Once the dispute is with the board, only the board decides.
  • Statuses are PENDING, PRE_ARBITRATION, TRIAGE, EVIDENCE, VOTING, RESOLVED, ESCALATED; outcomes BUYER | SELLER. Boards of 3, 5 and 7; the third hearing is decided by simple majority, with a tie going to the buyer. The losing side escalates with POST /v1/disputes/{dispute_id}/escalate, and enforcement is automatic once the outcome is final.
  • New event dispute.updated. New error codes: not_applicant, not_respondent, fully_refunded, amount_exceeds_unrefunded, dispute_with_board, offer_window_closed, offer_amount_invalid, no_pending_offer, evidence_window_closed, not_losing_party, escalation_window_closed, dispute_final. See Disputes.
2026-10-21 Added
Refunds
  • POST /v1/refunds — the seller agent reports a refund it paid from its own operational wallet. Nustro verifies the transfer on-chain before recording it, and the same tx_hash twice returns the existing record.
  • Refunds are capped, together with dispute payouts, at the original value, and blocked while a dispute is open (409 dispute_open). A refund lowers the transaction’s net value in both agents’ ratings and the seller’s escrow threshold, and carries no fee.
  • GET /v1/agents/{did}/refunds and the refund.recorded event. See Settlement.
2026-10-21 Breaking
Agent types replace economic roles
  • economic_role is now agent_type: PERSONAL (formerly CONSUMER) or BUSINESS. authorized_actions — purchase, sell, delegate — moves to the top level of POST /v1/agents and decides what an agent does. A business agent may buy, sell, or both; the separate ENTERPRISE role is gone.
  • Certificate tiers are provisional, personal, business; certificates carry aeap.agent_type and aeap.verification_tier. Renamed codes: cert_tier_type_mismatch, authorized_action_type_mismatch, field_not_allowed_for_type; markets on an agent that doesn’t sell return 403 action_not_permitted.
  • Principals: display_name, email, principal_type, and an optional inline verification your platform asserts — or set it later with PUT /v1/principals/{pid}/verification. Registration, activation and environment switch now check the tier against the type: verification_tier_insufficient, principal_type_mismatch.
  • POST /v1/agents/{did}/upgrade-type upgrades a personal agent to business in place, keeping its DID, rating history and dispute record.
  • Scope: minimum_counterparty_ar (formerly min_counterparty_rating), minimum_counterparty_cert_tier, and spending_limit as {amount, currency, window_days}. Sellers set markets and per-network wallets in one call, {markets, wallets}. The directory filters and returns agent_type.
  • Buyer agent and seller agent name the two sides of a transaction. The Agent Rating is one number per agent, blending its seller and buyer records by transaction value. Escrow is required of every business agent that sells, and a CONSTRAINED escrow suspends the whole agent.
2026-10-21 Changed
One scheme fee, from the seller's proceeds
  • Each settled transaction carries one scheme fee, taken from the seller’s proceeds — the buyer pays only the price. Refunds, disputes, escrow and sandbox carry no fee. See Settlement.
  • Examples now use Arc: arc-testnet in sandbox.
2026-08-12 Breaking
Error statuses: validation is 422, state conflicts are 409
  • Field and value validation across management endpoints moved 400 → 422, carrying field_errors[]. Affects missing_fields, invalid_economic_role, invalid_cert_tier, invalid_field, field_not_allowed_for_role, invalid_market_format, the counterparty-floor, spending-limit, escrow-config and dispute field codes, and more — see Errors for the full table.
  • Illegal transitions moved 400 → 409: invalid_status, use_activate_endpoint, escrow_constrained_cannot_reactivate.
  • The rule, from here on: 400 the request itself is wrong; 422 the values are invalid; 409 the object’s state forbids it. no_changes_requested stays 400 — an empty patch is a request problem, not a validation failure.
  • The response body was already canonical, so only the HTTP status changed. If you branch on status, update; if you branch on code, nothing breaks.
2026-08-12 Added
Agent catalogues, the scheme directory, and five new error codes
  • catalog_url on identity.profile — a link to your agent’s schema.org OfferCatalog. Provider and enterprise only; serializes null on consumers. Only the link is signed; Nustro never fetches the document. See Agent configuration.
  • Scheme directory — GET /v1/directory/agents, /agents/{did} and /changes: every certified agent on the scheme, with an incremental change feed. See Scheme directory.
  • Five error conditions that previously collapsed into a generic code are now branchable: agent_status_not_mutable, no_changes_requested, use_activate_endpoint, escrow_constrained_cannot_reactivate, catalog_url_not_permitted; plus cert_tier_role_mismatch and authorized_action_role_mismatch inside field_errors.
2026-08-11 Breaking
API v0.3 — the tenant is the Platform
  • Every /v1/customer(s)/* account path moved under /v1/platform. Old paths return 404 — a hard cutover, not a redirect.
  • Renamed: KYB status field customer_status → platform_status; profile customer_id → platform_id (plat_…); schemas Customer{Register, Registered, Profile} → Platform*; webhook event customer.verification_decided → platform.verification_decided.
  • New and additive: the Customers grouping resource (/v1/customers) — group principals under your own customers, filter principals by customer_id, suspend a customer to suspend its principals in one call. Opt-in: never set it and nothing changes.
  • Migration: a find/replace of the path prefix covers ~95% — the hand-fixes are the profile status read and the webhook event string.
2026-05-14 Added
Webhook endpoints
  • Register multiple endpoints, each with its own environment, event selection, and signing secret.
  • Deliveries carry Nustro-Signature, Nustro-Timestamp, and Nustro-Event-Id.
  • Event types: customer.verification_decided, transaction.settled, dispute.filed, dispute.resolved, agent.status_changed.
2026-05-14 Added
Activity log
  • GET /v1/customers/activity returns consequential management actions with actor, subject, and before/after changes.
  • Webhook URL, secret, and event-selection changes are recorded.
2026-05-02 Changed
Dispute eligibility is snapshotted at settlement
  • Transactions now carry dispute_window_days, dispute_window_closes_at, and the provider’s AID version, fixed at the moment of settlement.
  • Eligibility no longer resolves against the provider’s live AID — changing a dispute window no longer affects transactions that have already settled.
  • dispute_window_closes_at: null denotes final sale.
2026-04-18 Added
Escrow pre-funding
  • Principals may fund an agent’s escrow directly rather than accruing it from settlements.
  • Contributions still apply until the balance reaches threshold; above it, settlements credit in full to the operational account.
2026-04-03 Changed
Agent rating naming at the API boundary
  • pop_rating is now agent_rating in all responses.
  • The canonical scale remains 0.00–1.00; any multiplication is a display concern.
2026-03-21 Added
Management key rotation
  • POST /v1/customer/api-keys/rotate issues a replacement and revokes the previous key immediately.
  • grace_hours accepts 0–24 and currently defaults to 0. Send it explicitly.
2026-03-05 Deprecated
Principal key header
  • Nustro-Principal-Key is removed. There is one management credential per environment, sent as Nustro-Api-Key.
  • Agents authenticate per request with AEAP-Certificate, AEAP-Proof, and AEAP-Timestamp — never with a management key.
Following along

If you integrate against sandbox continuously, most entries here will already be familiar by the time they reach production. That is the intended use of sandbox: not just a place to build the first integration, but the place you notice what changed.