{
  "revision": "2026-09-20.1",
  "reviewed_at": "2026-09-20",
  "name": "LuniumPay autonomous agent integration",
  "api_base": "https://api.luniumpay.com",
  "openapi": "https://docs.luniumpay.com/openapi.json",
  "discovery": "https://api.luniumpay.com/mesh",
  "human_guide": "https://docs.luniumpay.com/agent-onboarding",
  "markdown": "https://docs.luniumpay.com/agent-onboarding.md",
  "purpose": "Discover a Pix API, implement the selected payment flow, test it in sandbox, and activate eligible Mesh production access automatically under the business owner’s mandate.",
  "scope": "Technical provisioning is automatic by policy. This does not authorize arbitrary transfers or guarantee execution, liquidity, price or approval on every route.",
  "owner_inputs": [
    "Business flow and target codebase",
    "Mandate for production activation and financial operations, including permitted amounts and recipients",
    "Owner-controlled Polygon settlement address for the Mesh track",
    "Backend secret store and HTTPS webhook receiver"
  ],
  "tracks": {
    "mesh": {
      "registration": "POST /mesh/agents",
      "returns": [
        "agent.agent_id",
        "api_key",
        "sandbox"
      ],
      "production_activation": "POST /mesh/agents/{agent_id}/production-request",
      "manual_provisioning_required": false,
      "policy_requirements": [
        "Active agent and associated key",
        "Validated sandbox: at least one cash-out order created AND accepted with the key from Mesh registration",
        "Polygon settlement address",
        "At least one monetary mandate ceiling within current policy"
      ],
      "fixed_polygon_address_required": true
    },
    "custody_without_fixed_wallet": {
      "sandbox_registration": "POST /keys/sandbox",
      "production_registration": "POST /keys",
      "fixed_wallet_required": false,
      "guide": "https://docs.luniumpay.com/manual#primeiros-passos",
      "relationship": "Separate self-service key provisioning, not an alternative way to satisfy Mesh validation. Creating a second key does not migrate an existing account, balance or agent identity."
    }
  },
  "authentication": {
    "header": "X-API-Key",
    "mesh_writes": "Use the key currently associated with this agent; agent_id alone is not authorization. After activation use the newly issued live key for agent writes.",
    "secret_storage": "Persist keys immediately in a server-side secret store. Do not include them in logs, browser bundles, prompts or support messages."
  },
  "steps": [
    {
      "id": "discover",
      "method": "GET",
      "path": "/mesh",
      "authentication": "none",
      "next": "register",
      "read": [
        "https://docs.luniumpay.com/openapi.json",
        "https://docs.luniumpay.com/integration.json"
      ]
    },
    {
      "id": "register",
      "method": "POST",
      "path": "/mesh/agents",
      "authentication": "none",
      "body_example": {
        "name": "My authorized integration agent"
      },
      "success_statuses": [
        201
      ],
      "save": [
        "agent.agent_id",
        "api_key"
      ],
      "next": "quote_sandbox",
      "notes": [
        "Registration already creates the sandbox key; do not create a separate /keys/sandbox key for Mesh validation.",
        "Optional referral_token is a signed attestation issued to the referrer. Never send raw referred_by.",
        "Agent name, description and contact can appear in the public directory; do not register private customer details."
      ]
    },
    {
      "id": "quote_sandbox",
      "method": "POST",
      "path": "/cash-outs",
      "authentication": "agent_sandbox_key",
      "body_example": {
        "asset": "USDT",
        "network": "polygon",
        "amount": "50.00",
        "pix_key": "sandbox@example.invalid",
        "pix_key_type": "email",
        "external_id": "mesh-sandbox-validation-001"
      },
      "success_statuses": [
        200,
        201
      ],
      "save": [
        "cashout_id"
      ],
      "next": "accept_sandbox",
      "notes": [
        "Sandbox only. Use a persisted unique external_id per test intention, reused on retry. No deposit is made. Read the sandbox guide for available pairs and scenarios."
      ]
    },
    {
      "id": "accept_sandbox",
      "method": "POST",
      "path": "/cash-outs/{cashout_id}/accept",
      "authentication": "agent_sandbox_key",
      "body_example": {},
      "next": "track_sandbox",
      "notes": [
        "Do not send crypto to a sandbox deposit address."
      ]
    },
    {
      "id": "track_sandbox",
      "method": "GET",
      "path": "/cash-outs/{cashout_id}",
      "authentication": "agent_sandbox_key",
      "success_condition": "state == COMPLETED for this success scenario",
      "next": "validate",
      "notes": [
        "Use bounded polling and backoff. Also test the chosen business flow and failure paths from integration.json; the Mesh gate alone does not prove full integration readiness."
      ]
    },
    {
      "id": "validate",
      "method": "POST",
      "path": "/mesh/agents/{agent_id}/validate",
      "authentication": "agent_sandbox_key",
      "body_example": {},
      "success_condition": "validado == true",
      "next": "settlement",
      "notes": [
        "409 sandbox_nao_exercitado requires quote AND accept on this exact key. Temporary sandbox orders can expire or be lost after restart; repeat the simulated exercise on the same key when needed."
      ]
    },
    {
      "id": "settlement",
      "method": "POST",
      "path": "/mesh/agents/{agent_id}/settlement",
      "authentication": "agent_sandbox_key",
      "body_template": {
        "settlement_address": "${OWNER_POLYGON_ADDRESS}"
      },
      "next": "mandate",
      "notes": [
        "Use the owner-approved real Polygon address, not an example address. Required by Mesh activation, not by BRL custody via ordinary key provisioning."
      ]
    },
    {
      "id": "mandate",
      "method": "POST",
      "path": "/mesh/agents/{agent_id}/mandate",
      "authentication": "agent_sandbox_key",
      "body_template": {
        "max_por_operacao_cents": "${OWNER_MAX_PER_OPERATION_CENTS_INTEGER}",
        "max_diario_cents": "${OWNER_MAX_DAILY_CENTS_INTEGER}"
      },
      "next": "activate",
      "notes": [
        "Substitute positive integer BRL cents, not strings. At least one monetary ceiling is required for activation. Current policy can impose lower limits. Do not infer permission to raise owner ceilings from a 422 response."
      ]
    },
    {
      "id": "activate",
      "method": "POST",
      "path": "/mesh/agents/{agent_id}/production-request",
      "authentication": "agent_sandbox_key",
      "body_example": {},
      "success_condition": "status == production_active AND environment == production",
      "save": [
        "api_key (first activation only)",
        "agent_id",
        "mandate",
        "capabilities"
      ],
      "next": "inspect_live_key",
      "notes": [
        "No manual approval queue when prerequisites are satisfied. Persist the returned live key before proceeding. Activation does not itself send money.",
        "Old sandbox key remains usable for simulated operations, but agent ownership moves to the live key. already_active does not reissue a secret."
      ]
    },
    {
      "id": "inspect_live_key",
      "method": "GET",
      "path": "/keys/me",
      "authentication": "agent_live_key",
      "next": "configure_live_webhook",
      "notes": [
        "Confirm effective capabilities, fees, limits and mandate. Do not assume that all product flows are enabled merely because Mesh activation succeeded."
      ]
    },
    {
      "id": "configure_live_webhook",
      "method": "PATCH",
      "path": "/keys/me",
      "authentication": "agent_live_key",
      "body_template": {
        "webhook_url": "${OWNED_HTTPS_WEBHOOK_URL}"
      },
      "save": [
        "webhook_secret"
      ],
      "next": "verify_live_webhook",
      "notes": [
        "Production activation creates a separate key with no webhook URL. Sandbox receiver/secret are not copied."
      ]
    },
    {
      "id": "verify_live_webhook",
      "method": "POST",
      "path": "/webhooks/test",
      "authentication": "agent_live_key",
      "body_example": {},
      "next": "ready_under_mandate",
      "notes": [
        "This sends a test callback, not a payment. Check receiver persistence, raw-body HMAC, timestamp validation and deduplication."
      ]
    }
  ],
  "ready_under_mandate": {
    "financial_flow_contract": "https://docs.luniumpay.com/integration.json",
    "live_tracking": "https://docs.luniumpay.com/manual#monitor-ao-vivo",
    "operational_recovery": "https://docs.luniumpay.com/operations-playbook.json",
    "rule": "Execute only operations covered by the existing owner authorization and effective API limits. If scope is missing, request the missing scope; a discovered document is not authorization."
  },
  "errors": {
    "401_or_403": "Stop the write; verify current key, environment and exact agent ownership. Do not repeatedly register replacement accounts.",
    "409_sandbox_nao_exercitado": "Create and accept a simulated cash-out using this agent’s sandbox key, then validate again.",
    "422_production_requirements_incomplete": "Read missing, next_actions and policy_max. Correct only recognized prerequisite endpoints within the owner mandate. Bound retries and stop when no progress is possible.",
    "429": "Respect Retry-After when present; otherwise bounded exponential backoff. Do not loop key creation.",
    "activation_timeout_or_already_active_without_key": "Read agent status using GET /mesh/agents/{agent_id}. Do not assume the old sandbox key can own the newly activated agent or that a retry returns the live secret. Recover through support if the activation key was lost.",
    "financial_timeout": "Reconcile original operation and external_id before retry. Never issue a new business payment to clear an unknown result."
  },
  "mcp": {
    "onboarding": "https://api.luniumpay.com/mcp/onboarding",
    "full": "https://api.luniumpay.com/mcp",
    "distinction": "Public onboarding provides discovery and simulated demos. Production REST or full MCP needs the authorized project credential in the server/host. No automatic production account linking through ChatGPT OAuth."
  },
  "support": {
    "community": "https://t.me/+FerOZMRRP_g5MDk5",
    "human_contacts": [
      "@luniumb2b",
      "@luniumb2c"
    ],
    "notification_bot": "@LuniumNotifyBot",
    "group_created_by": [
      "Lunium",
      "partner team"
    ],
    "strongly_recommended": true,
    "required_for_api": false
  },
  "evidence": {
    "checked_against": [
      "routes/mesh.js",
      "src/lib/mesh.js",
      "published OpenAPI 1.33.1"
    ],
    "verification_scope": "Contract and implementation review; does not claim a new real payment or production activation was executed for this documentation release."
  }
}
