> ## Documentation Index
> Fetch the complete documentation index at: https://docs.natural.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> When building application code, use `@naturalpay/sdk` for TypeScript or `naturalpay` for Python.
> When operating Natural directly for a user, use the payments MCP at `https://mcp.natural.com`.
> When searching Natural documentation, use the docs MCP at `https://docs.natural.com/mcp`.
> Use the Natural CLI for terminal and CI automation.
> Use REST only for unsupported languages or when the user explicitly requests raw HTTP.
> Start integration development and testing in the sandbox. Do not use production unless the user explicitly requests it.
> For sandbox requests that require `customerPartyId`, list customers first. Reuse only the intended fixture; otherwise create a customer.
> REST and SDK amounts use integer minor units. Payments MCP amounts use decimal strings with a required currency code.

# Sandbox from MCP, CLI, and SDKs

> Connect to the Natural Sandbox

To start with the sandbox environment in Natural, get a sandbox key (`sk_ntl_sandbox_…`, `ak_ntl_sandbox_…`) by switching the [dashboard](/guides/platform/dashboard) to Sandbox.

Simulation actions, the counterparty side of each flow, are first-class on every surface:

| Surface  | Where simulations live                                                                                         |
| -------- | -------------------------------------------------------------------------------------------------------------- |
| REST API | [`POST /simulations/*`](/api-reference/simulations/create-test-customer), grouped with the resources they test |
| SDKs     | `client.simulations` in [TypeScript and Python](/guides/platform/sdks)                                         |
| CLI      | [`natural simulations <verb>`](/guides/platform/cli) commands                                                  |
| MCP      | Sandbox-only tools on `mcp.sandbox.natural.com`                                                                |

## SDKs

Point the client at the sandbox and put your agent's sandbox key in `NATURAL_API_KEY`. Your integration code is unchanged; `client.simulations` acts as the counterparty.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import Natural from "@naturalpay/sdk";

  // NATURAL_API_KEY=ak_ntl_sandbox_...
  const client = new Natural({
    instanceId: "sandbox-run-1",
    baseUrl: "https://api.sandbox.natural.com",
  });

  // Invite a test customer; one pending invitation is created per agent
  const invited = await client.simulations.inviteCustomer({
    agentIds: ["agt_550e8400e29b41d4a716446655440000"],
    idempotencyKey: "test-customer-1",
  });
  const customerId = invited.meta.customer.partyId;

  // Accept the invitation as the test customer
  await client.simulations.acceptCustomerInvitation({
    invitationId: invited.data[0].id,
    partyId: customerId,
    idempotencyKey: "accept-invitation-1",
  });

  // Fund it so payments on its behalf can settle
  await client.simulations.fundCustomer({
    customerId,
    amount: 250000, // cents - $2,500.00
    currency: "USD",
    idempotencyKey: "fund-customer-1",
  });

  // Run your integration exactly as it runs in production
  const payment = await client.payments.create({
    amount: 10000,
    currency: "USD",
    counterparty: { type: "email", value: "payment-recipient@sandbox.natural.test" },
    customerPartyId: customerId,
    idempotencyKey: "pay-1",
  });
  ```

  ```python Python theme={null}
  from naturalpay import Natural

  # NATURAL_API_KEY=ak_ntl_sandbox_...
  client = Natural(
      instance_id="sandbox-run-1",
      base_url="https://api.sandbox.natural.com",
  )

  # Invite a test customer; one pending invitation is created per agent
  invited = client.simulations.invite_customer(
      agent_ids=["agt_550e8400e29b41d4a716446655440000"],
      idempotency_key="test-customer-1",
  )
  customer_id = invited.meta.customer.party_id

  # Accept the invitation as the test customer
  client.simulations.accept_customer_invitation(
      invitation_id=invited.data[0].id,
      party_id=customer_id,
      idempotency_key="accept-invitation-1",
  )

  # Fund it so payments on its behalf can settle
  client.simulations.fund_customer(
      customer_id=customer_id,
      amount=250000,  # cents - $2,500.00
      currency="USD",
      idempotency_key="fund-customer-1",
  )

  # Run your integration exactly as it runs in production
  payment = client.payments.create(
      amount=10000,
      currency="USD",
      counterparty={"type": "email", "value": "payment-recipient@sandbox.natural.test"},
      customer_party_id=customer_id,
      idempotency_key="pay-1",
  )
  ```
</CodeGroup>

Both SDKs expose the full simulation surface. TypeScript names methods in camelCase, Python in snake\_case:

| Method                                                   | Simulates                                                                                              |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `inviteCustomer`                                         | [A test customer with a pending invitation per agent](/api-reference/simulations/create-test-customer) |
| `fundCustomer`                                           | [A deposit into a test customer's wallet](/api-reference/simulations/fund-test-customer)               |
| `linkExternalAccount`                                    | [A linked test bank account](/api-reference/simulations/link-test-bank-account)                        |
| `completePaymentClaim`                                   | [An unregistered payee claiming your payment](/api-reference/simulations/complete-payment-claim)       |
| `fulfillPaymentRequest` / `declinePaymentRequest`        | [The payer answering your request](/api-reference/simulations/fulfill-payment-request)                 |
| `acceptCustomerInvitation` / `declineCustomerInvitation` | [The customer answering your invitation](/api-reference/simulations/accept-customer-invitation)        |
| `revokeAgentConnection`                                  | [The customer revoking your agent](/api-reference/simulations/revoke-agent-connection)                 |

## CLI

Export a sandbox key and the sandbox base URL; every command then runs against the sandbox:

```bash theme={null}
export NATURAL_API_KEY=sk_ntl_sandbox_abc123...
export NATURAL_BASE_URL=https://api.sandbox.natural.com

# Invite a test customer; the response carries the customer party ID and invitation IDs
natural simulations inviteCustomer \
  --json '{"agentIds": ["agt_019cd1798d637a4da75dce386343931d"]}' \
  --idempotency-key "$(uuidgen)"

# Accept the invitation as the test customer
natural simulations acceptCustomerInvitation \
  --invitation-id adi_019cd1798d637a4da75dce386343931d \
  --json '{"partyId": "pty_7c9e6679e29b41d4a716446655440001"}' \
  --idempotency-key "$(uuidgen)"

# Fund it, then pay on its behalf exactly as in production
natural simulations fundCustomer \
  --customer-id pty_7c9e6679e29b41d4a716446655440001 \
  --amount 250000 \
  --currency USD \
  --idempotency-key "$(uuidgen)"
```

`--base-url` works per command if you prefer not to export `NATURAL_BASE_URL`.

<Note>
  `natural login` signs into production. Against the sandbox, authenticate with a sandbox key.
</Note>

## MCP

Natural runs a sandbox peer of the hosted MCP server at **`https://mcp.sandbox.natural.com`**. Connect it exactly like the [production server](/guides/platform/mcp), alongside it if you like:

```json theme={null}
{
  "mcpServers": {
    "natural": { "url": "https://mcp.natural.com" },
    "natural-sandbox": { "url": "https://mcp.sandbox.natural.com" }
  }
}
```

The sandbox peer exposes every production tool. On this peer, `invite_customer` creates a synthetic test customer with pending invitations instead of emailing a real person. Below are the tools that are sandbox-only:

| Tool                                   | What it does                                          |
| -------------------------------------- | ----------------------------------------------------- |
| `simulate_customer_deposit`            | Add test funds to a connected customer                |
| `link_test_bank_account`               | Link a synthetic bank account to your party           |
| `simulate_payment_claim_completion`    | Complete a held payment as the claim recipient        |
| `simulate_payment_request_fulfillment` | Fulfill your payment request as the test payer        |
| `simulate_payment_request_decline`     | Decline your payment request as the test payer        |
| `simulate_customer_invitation_accept`  | Accept your customer invitation as the test customer  |
| `simulate_customer_invitation_decline` | Decline your customer invitation as the test customer |
| `simulate_agent_connection_revoke`     | Revoke an agent's access as the test customer         |
