DropEngine · Financial Layer
STAGING DEVELOPER GUIDE

Integrate a controlled agent payment lifecycle.

The financial API is a separate control-plane API around the existing paid service catalog. It does not replace an x402 client and it does not hold signing authority.

Quickstart

  1. Request an operator-issued staging agent_id and agent_token.
  2. Create one intent with an opaque Idempotency-Key.
  3. Run trust, then authorize spend. Stop if the decision is deny or pending approval.
  4. Only after authorization, submit an unsigned transfer for preflight and request a route preview.
  5. Reconcile only after an independent payment client has a transaction reference.

Use the public demo to understand the states without credentials or a wallet.

1. Create an intent

POST /api/financial/intents → expected transition: CREATED

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "purpose": "Screen a URL before reading it",
  "target": "check_url",
  "tool_name": "check_url",
  "amount": "0.005",
  "asset": "USDC",
  "network": "base-sepolia"
}

Required header: Idempotency-Key: a-unique-opaque-value

Response

{
  "success": true,
  "intent": {
    "id": "fi_…",
    "state": "CREATED",
    "amount": "0.005",
    "asset": "USDC",
    "network": "eip155:84532"
  },
  "replayed": false
}

Representative error

{
  "success": false,
  "error": {
    "code": "IDEMPOTENCY_KEY_REQUIRED",
    "message": "Send an Idempotency-Key header (8–128 opaque characters)."
  }
}

Send Idempotency-Key: an opaque, unique value with every creation request.

2. Check trust

POST /api/financial/trust/check → expected transition: TRUST_CHECKED

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "intent_id": "fi_…",
  "chain": "base-sepolia",
  "screen_wallet": false
}

Response

{
  "success": true,
  "assessment_id": "cuid",
  "status": "insufficient_data",
  "trust_score": null,
  "risk_level": "unknown",
  "confidence": "insufficient_data"
}

Representative error

{
  "success": false,
  "error": {
    "code": "INVALID_STATE_TRANSITION",
    "message": "Trust can only be refreshed before spend authorization."
  }
}

Optional wallet screening is explicit; do not send a wallet unless your integration has a reason to assess it.

3. Authorize spend

POST /api/financial/authorize-spend → expected transition: AUTHORIZED or AUTHORIZATION_PENDING

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "intent_id": "fi_…"
}

Response

{
  "success": true,
  "authorization_id": "fa_…",
  "decision": "require_approval",
  "approval_status": "pending",
  "reason": "Policy requires owner approval."
}

Representative error

{
  "success": false,
  "error": {
    "code": "SPEND_NOT_AUTHORIZED",
    "message": "A later step was attempted before a valid authorization."
  }
}

An allow decision moves the intent to AUTHORIZED. A require_approval decision waits for an authenticated operator action.

4. Preflight an unsigned transfer

POST /api/financial/preflight → expected transition: PREFLIGHT_PASSED

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "intent_id": "fi_…",
  "authorization_id": "fa_…",
  "expected_target": "0xYourConfiguredStagingRecipient",
  "expected_token": "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
  "transaction": {
    "chain": "base-sepolia",
    "from": "0xYourWallet",
    "to": "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
    "value": "0",
    "data": "0xa9059cbb…"
  }
}

Response

{
  "success": true,
  "preflight_id": "pf_…",
  "safe": true,
  "risk_level": "low",
  "warnings": [],
  "replayed": false
}

Representative error

{
  "success": false,
  "error": {
    "code": "PREFLIGHT_FAILED",
    "message": "Transaction simulation failed; no signing or broadcast was attempted."
  }
}

Use your verified staging recipient and a real unsigned ERC-20 transfer calldata. The API never signs or broadcasts it.

5. Request a payment route preview

POST /api/financial/payment-route → expected transition: PAYMENT_READY

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "intent_id": "fi_…",
  "authorization_id": "fa_…",
  "preflight_id": "pf_…",
  "preferred_protocols": [
    "x402"
  ]
}

Response

{
  "success": true,
  "route_id": "fr_…",
  "selected_protocol": "x402",
  "network": "eip155:84532",
  "asset": "USDC",
  "amount": "0.005",
  "status": "READY",
  "payment_requested": false
}

Representative error

{
  "success": false,
  "error": {
    "code": "PREFLIGHT_NOT_PASSED",
    "message": "A matching successful transaction preflight is required."
  }
}

A READY route describes the current paid endpoint and requirements. It does not sign, broadcast or settle a payment.

6. Reconcile later

POST /api/financial/reconcile → expected transition: RECONCILED or RECONCILIATION_REQUIRED

Request

{
  "agent_id": "your_agent_id",
  "agent_token": "your_32_character_or_longer_agent_token",
  "intent_id": "fi_…"
}

Response

{
  "success": true,
  "reconciliation_id": "rc_…",
  "status": "needs_review",
  "reason": "A confirmed x402 transaction hash is required; the route itself never initiates a payment."
}

Representative error

{
  "success": false,
  "error": {
    "code": "ROUTE_NOT_READY",
    "message": "No payment route exists for this intent."
  }
}

Add payment_reference only after an independent x402 payment has a confirmed transaction hash.

7. Read the ledger

GET /api/financial/ledger?limit=100 → expected transition: Read only

Request

{
  "headers": {
    "X-Agent-Id": "your_agent_id",
    "X-Agent-Token": "your_32_character_or_longer_agent_token"
  }
}

Response

{
  "success": true,
  "entries": [
    {
      "event_type": "intent_created",
      "status": "created",
      "intent_id": "fi_…"
    }
  ]
}

Representative error

{
  "success": false,
  "error": {
    "code": "AGENT_AUTH_FAILED",
    "message": "Agent identity or token is not valid."
  }
}

Ledger rows are append-only and scoped to the authenticated customer account (tenant) and agent identity. Send your API key via Authorization or x-api-key; agent identity comes from the headers or request body.

API reference

These routes and status codes are derived from the staging API handlers and validation rules. Fields listed as optional are not required to begin the lifecycle.

MethodPath / authRequired fieldsStatus codes
POST/api/financial/intentsAgent identity in body + Idempotency-Key headeragent_id, agent_token, purpose, target, amount, asset, network200, 400, 401, 409, 503
POST/api/financial/trust/checkAgent identity in bodyagent_id, agent_token; intent_id optional200, 400, 401, 404, 409
POST/api/financial/authorize-spendAgent identity in bodyagent_id, agent_token, intent_id200, 400, 401, 404, 409
POST/api/financial/preflightAgent identity in bodyagent_id, agent_token, intent_id, authorization_id, expected_target, expected_token, transaction200, 400, 401, 404, 409, 422
POST/api/financial/payment-routeAgent identity in bodyagent_id, agent_token, intent_id, authorization_id, preflight_id200, 400, 401, 404, 409, 422, 503
POST/api/financial/reconcileAgent identity in bodyagent_id, agent_token, intent_id; payment_reference optional200, 400, 401, 404, 409
GET/api/financial/ledgerX-Agent-Id + X-Agent-Token headerslimit optional (1–200)200, 400, 401

Customer onboarding readiness

Operator provides

Tenant/customer identity, an opaque agent ID and token, initial policy limits, allowed networks/assets, and a staging environment selection.

Customer integrates

Stores its token in a secret manager, sends idempotency keys, validates x402 offers independently, and keeps signing/payment software outside this API.

Before production

Implement tenant isolation, customer credential issuance and rotation, gateway rate limits, webhook/callback delivery, support runbooks and a reviewed staging-to-production migration.

Webhook/callback delivery and production tenant isolation are not part of the current staging MVP. Poll intent and ledger endpoints during a pilot until an explicit webhook contract exists.