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

# Stripe (read-only)

The io.b3os/stripe pack: 14 actions and 2 triggers with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.

`io.b3os/stripe` 1.0.0 · `payments`, `billing` · MIT

Read your Stripe account with your own restricted key: balance, customers (list, get, search), charges, payment intents, invoices with line items, subscriptions, products, prices and events, plus triggers for new events (polled, or delivered to a webhook endpoint you add in the Stripe Dashboard). Read-only: nothing here creates, changes or refunds anything. Amounts are in the smallest currency unit (cents). Test-mode keys read test data.

Every call's result carries `upstream_status` and `timing`: `validate_ms`, `inject_ms`, `render_ms`, `upstream_ms`, `map_ms` and `total_ms`. `upstream` is the service's time; the others are B3OS's own ([call actions](/actions/call)). The snippets below show no timing values, because a fixture records none.

## Connection

`secret_key`, type `bearer`: Stripe restricted key.

A restricted key (rk_live_ or rk_test_) with Read access to the resources the actions use (Balance, Customers, Charges, PaymentIntents, Invoices, Subscriptions, Products, Prices, Events). A secret key works too but grants far more than this pack needs.

How to get one: [docs.stripe.com](https://docs.stripe.com/keys#limit-access).

The credential is sent only to `api.stripe.com`.

Store the credential once as a [vault connection](/vault) for this pack and key, then name its id in a call's `connections`. Leave the key out and B3OS uses the project's newest connection for the pack and key without a `subject` ([connections](/actions/call#connections)).

Hosts it reaches: `api.stripe.com`.

## Actions

| Action | Effect | MCP tool | Title |
|---|---|---|---|
| [`get-balance`](/actions/catalog/stripe#stripe-get-balance) | read | `stripe__get-balance` | Get balance |
| [`list-customers`](/actions/catalog/stripe#stripe-list-customers) | read | `stripe__list-customers` | List customers |
| [`get-customer`](/actions/catalog/stripe#stripe-get-customer) | read | `stripe__get-customer` | Get customer |
| [`search-customers`](/actions/catalog/stripe#stripe-search-customers) | read | `stripe__search-customers` | Search customers |
| [`list-charges`](/actions/catalog/stripe#stripe-list-charges) | read | `stripe__list-charges` | List charges |
| [`list-payment-intents`](/actions/catalog/stripe#stripe-list-payment-intents) | read | `stripe__list-payment-intents` | List payment intents |
| [`get-payment-intent`](/actions/catalog/stripe#stripe-get-payment-intent) | read | `stripe__get-payment-intent` | Get payment intent |
| [`list-invoices`](/actions/catalog/stripe#stripe-list-invoices) | read | `stripe__list-invoices` | List invoices |
| [`get-invoice`](/actions/catalog/stripe#stripe-get-invoice) | read | `stripe__get-invoice` | Get invoice |
| [`list-subscriptions`](/actions/catalog/stripe#stripe-list-subscriptions) | read | `stripe__list-subscriptions` | List subscriptions |
| [`list-products`](/actions/catalog/stripe#stripe-list-products) | read | `stripe__list-products` | List products |
| [`list-prices`](/actions/catalog/stripe#stripe-list-prices) | read | `stripe__list-prices` | List prices |
| [`list-events`](/actions/catalog/stripe#stripe-list-events) | read | `stripe__list-events` | List events |
| [`get-event`](/actions/catalog/stripe#stripe-get-event) | read | `stripe__get-event` | Get event |

get-balance

**Get balance.** Funds in the Stripe balance per currency: available now and pending (not yet settled), in the smallest currency unit.

Ref `io.b3os/stripe/get-balance@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__get-balance`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/get-balance@1",
          "input": {},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/get-balance@1",
      input: {},
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/get-balance@1",
        "input": {},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {"name": "stripe__get-balance", "arguments": {}}
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__get-balance` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get balance (documented response shape, example values). From the bundle's `fixtures/get-balance.json`, not a live call.

```json
{
  "available": [{"amount": 1203400, "currency": "usd"}],
  "pending": [{"amount": 54900, "currency": "usd"}],
  "livemode": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-customers

**List customers.** Customers, newest first, optionally only those with an exact email. Page with starting_after = the last id while has_more is true.

Ref `io.b3os/stripe/list-customers@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-customers`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-customers@1",
          "input": {"email": "buyer@example.com", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-customers@1",
      input: { email: "buyer@example.com", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-customers@1",
        "input": {"email": "buyer@example.com", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-customers",
        "arguments": {"email": "buyer@example.com", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-customers` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List customers (documented response shape, example values). From the bundle's `fixtures/list-customers.json`, not a live call.

```json
{
  "data": [
    {
      "id": "cus_Qexample0001",
      "email": "buyer@example.com",
      "name": "Jane Buyer",
      "description": null,
      "created": 1792970000,
      "currency": "usd",
      "balance": 0,
      "delinquent": false,
      "livemode": false,
      "metadata": {"crm_id": "8812"}
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

get-customer

**Get customer.** One customer by id: email, name, description, currency, credit balance, delinquent flag and metadata.

Ref `io.b3os/stripe/get-customer@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__get-customer`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/get-customer@1",
          "input": {"id": "cus_Qexample0001"},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/get-customer@1",
      input: { id: "cus_Qexample0001" },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/get-customer@1",
        "input": {"id": "cus_Qexample0001"},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__get-customer",
        "arguments": {"id": "cus_Qexample0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__get-customer` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get customer (documented response shape, example values). From the bundle's `fixtures/get-customer.json`, not a live call.

```json
{
  "id": "cus_Qexample0001",
  "email": "buyer@example.com",
  "name": "Jane Buyer",
  "description": null,
  "created": 1792970000,
  "currency": "usd",
  "balance": 0,
  "delinquent": false,
  "livemode": false,
  "metadata": {"crm_id": "8812"}
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

search-customers

**Search customers.** Search customers with Stripe's search query language, for example email:'jane@example.com', name~'jane', metadata['crm_id']:'8812' or created&gt;1700000000, combined with AND/OR. Newly changed customers can take up to a minute to appear. Page with next_page.

Ref `io.b3os/stripe/search-customers@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__search-customers`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/search-customers@1",
          "input": {"query": "metadata['\''crm_id'\'']:'\''8812'\''", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/search-customers@1",
      input: { query: "metadata['crm_id']:'8812'", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/search-customers@1",
        "input": {"query": "metadata['crm_id']:'8812'", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__search-customers",
        "arguments": {"query": "metadata['crm_id']:'8812'", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__search-customers` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Search customers (documented response shape, example values). From the bundle's `fixtures/search-customers.json`, not a live call.

```json
{
  "data": [
    {
      "id": "cus_Qexample0001",
      "email": "buyer@example.com",
      "name": "Jane Buyer",
      "description": null,
      "created": 1792970000,
      "currency": "usd",
      "balance": 0,
      "delinquent": false,
      "livemode": false,
      "metadata": {"crm_id": "8812"}
    }
  ],
  "has_more": false,
  "next_page": null
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-charges

**List charges.** Charges, newest first, optionally for one customer: amount, refunded amount, status, paid and refunded flags, failure message and receipt URL.

Ref `io.b3os/stripe/list-charges@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-charges`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-charges@1",
          "input": {"customer": "cus_Qexample0001", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-charges@1",
      input: { customer: "cus_Qexample0001", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-charges@1",
        "input": {"customer": "cus_Qexample0001", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-charges",
        "arguments": {"customer": "cus_Qexample0001", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-charges` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List charges (documented response shape, example values). From the bundle's `fixtures/list-charges.json`, not a live call.

```json
{
  "data": [
    {
      "id": "ch_3Qexample0001",
      "amount": 4900,
      "amount_refunded": 0,
      "currency": "usd",
      "status": "succeeded",
      "paid": true,
      "refunded": false,
      "customer": "cus_Qexample0001",
      "description": "Pro plan",
      "payment_intent": "pi_3Qexample0001",
      "failure_message": null,
      "receipt_url": "https://pay.stripe.com/receipts/payment/CAcaFwoV",
      "created": 1792970390
    }
  ],
  "has_more": true
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-payment-intents

**List payment intents.** Payment intents, newest first, optionally for one customer, with amount, amount received, status and latest charge.

Ref `io.b3os/stripe/list-payment-intents@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-payment-intents`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-payment-intents@1",
          "input": {"customer": "cus_Qexample0001", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-payment-intents@1",
      input: { customer: "cus_Qexample0001", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-payment-intents@1",
        "input": {"customer": "cus_Qexample0001", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-payment-intents",
        "arguments": {"customer": "cus_Qexample0001", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-payment-intents` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List payment intents (documented response shape, example values). From the bundle's `fixtures/list-payment-intents.json`, not a live call.

```json
{
  "data": [
    {
      "id": "pi_3Qexample0001",
      "amount": 4900,
      "amount_received": 4900,
      "currency": "usd",
      "status": "succeeded",
      "customer": "cus_Qexample0001",
      "description": "Pro plan",
      "latest_charge": "ch_3Qexample0001",
      "created": 1792970380,
      "metadata": {}
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

get-payment-intent

**Get payment intent.** One payment intent by id: amount, amount received, currency, status, customer, latest charge and metadata.

Ref `io.b3os/stripe/get-payment-intent@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__get-payment-intent`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/get-payment-intent@1",
          "input": {"id": "pi_3Qexample0001"},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/get-payment-intent@1",
      input: { id: "pi_3Qexample0001" },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/get-payment-intent@1",
        "input": {"id": "pi_3Qexample0001"},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__get-payment-intent",
        "arguments": {"id": "pi_3Qexample0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__get-payment-intent` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get payment intent (documented response shape, example values). From the bundle's `fixtures/get-payment-intent.json`, not a live call.

```json
{
  "id": "pi_3Qexample0001",
  "amount": 4900,
  "amount_received": 4900,
  "currency": "usd",
  "status": "succeeded",
  "customer": "cus_Qexample0001",
  "description": "Pro plan",
  "latest_charge": "ch_3Qexample0001",
  "created": 1792970380,
  "metadata": {}
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-invoices

**List invoices.** Invoices, newest first, filtered by customer, subscription or status (draft, open, paid, uncollectible, void), with totals, amounts due and paid, due date, hosted page and PDF links and line items.

Ref `io.b3os/stripe/list-invoices@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-invoices`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-invoices@1",
          "input": {"customer": "cus_Qexample0001", "status": "paid", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-invoices@1",
      input: { customer: "cus_Qexample0001", status: "paid", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-invoices@1",
        "input": {"customer": "cus_Qexample0001", "status": "paid", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-invoices",
        "arguments": {"customer": "cus_Qexample0001", "status": "paid", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-invoices` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List invoices (documented response shape, example values). From the bundle's `fixtures/list-invoices.json`, not a live call.

```json
{
  "data": [
    {
      "id": "in_1Qexample0001",
      "number": "B3D4F-0007",
      "status": "paid",
      "customer": "cus_Qexample0001",
      "customer_email": "buyer@example.com",
      "currency": "usd",
      "total": 4900,
      "amount_due": 4900,
      "amount_paid": 4900,
      "amount_remaining": 0,
      "due_date": null,
      "created": 1792970300,
      "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1Qexample/test_YWNjdF8x",
      "invoice_pdf": "https://pay.stripe.com/invoice/acct_1Qexample/test_YWNjdF8x/pdf",
      "lines": [
        {
          "description": "1 x Pro (at $49.00 / month)",
          "amount": 4900,
          "quantity": 1
        }
      ]
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

get-invoice

**Get invoice.** One invoice by id with status, number, totals, amounts due, paid and remaining, due date, links and line items.

Ref `io.b3os/stripe/get-invoice@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__get-invoice`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/get-invoice@1",
          "input": {"id": "in_1Qexample0001"},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/get-invoice@1",
      input: { id: "in_1Qexample0001" },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/get-invoice@1",
        "input": {"id": "in_1Qexample0001"},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__get-invoice",
        "arguments": {"id": "in_1Qexample0001"}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__get-invoice` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get invoice (documented response shape, example values). From the bundle's `fixtures/get-invoice.json`, not a live call.

```json
{
  "id": "in_1Qexample0001",
  "number": "B3D4F-0007",
  "status": "paid",
  "customer": "cus_Qexample0001",
  "customer_email": "buyer@example.com",
  "currency": "usd",
  "total": 4900,
  "amount_due": 4900,
  "amount_paid": 4900,
  "amount_remaining": 0,
  "due_date": null,
  "created": 1792970300,
  "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1Qexample/test_YWNjdF8x",
  "invoice_pdf": "https://pay.stripe.com/invoice/acct_1Qexample/test_YWNjdF8x/pdf",
  "lines": [
    {
      "description": "1 x Pro (at $49.00 / month)",
      "amount": 4900,
      "quantity": 1
    }
  ]
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-subscriptions

**List subscriptions.** Subscriptions filtered by customer, price or status (default: everything not canceled), with status, renewal time, cancel-at-period-end flag and items (price, product, quantity, unit amount, interval).

Ref `io.b3os/stripe/list-subscriptions@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-subscriptions`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-subscriptions@1",
          "input": {"customer": "cus_Qexample0001", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-subscriptions@1",
      input: { customer: "cus_Qexample0001", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-subscriptions@1",
        "input": {"customer": "cus_Qexample0001", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-subscriptions",
        "arguments": {"customer": "cus_Qexample0001", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-subscriptions` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List subscriptions (documented response shape, example values). From the bundle's `fixtures/list-subscriptions.json`, not a live call.

```json
{
  "data": [
    {
      "id": "sub_1Qexample0001",
      "status": "active",
      "customer": "cus_Qexample0001",
      "cancel_at_period_end": false,
      "current_period_end": 1795648800,
      "created": 1790380000,
      "items": [
        {
          "price": "price_1Qexample0001",
          "product": "prod_Qexample0001",
          "quantity": 1,
          "unit_amount": 4900,
          "interval": "month"
        }
      ]
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-products

**List products.** Products, newest first, optionally only active ones: name, description, active flag, default price and metadata.

Ref `io.b3os/stripe/list-products@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-products`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-products@1",
          "input": {"active": true, "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-products@1",
      input: { active: true, limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-products@1",
        "input": {"active": True, "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-products",
        "arguments": {"active": true, "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-products` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List products (documented response shape, example values). From the bundle's `fixtures/list-products.json`, not a live call.

```json
{
  "data": [
    {
      "id": "prod_Qexample0001",
      "name": "Pro",
      "description": "Pro plan",
      "active": true,
      "default_price": "price_1Qexample0001",
      "created": 1790000000,
      "metadata": {}
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-prices

**List prices.** Prices, newest first, optionally for one product or only active ones: unit amount, currency, one-time or recurring interval, nickname and lookup key.

Ref `io.b3os/stripe/list-prices@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-prices`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-prices@1",
          "input": {"product": "prod_Qexample0001", "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-prices@1",
      input: { product: "prod_Qexample0001", limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-prices@1",
        "input": {"product": "prod_Qexample0001", "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-prices",
        "arguments": {"product": "prod_Qexample0001", "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-prices` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List prices (documented response shape, example values). From the bundle's `fixtures/list-prices.json`, not a live call.

```json
{
  "data": [
    {
      "id": "price_1Qexample0001",
      "product": "prod_Qexample0001",
      "active": true,
      "currency": "usd",
      "unit_amount": 4900,
      "type": "recurring",
      "interval": "month",
      "nickname": null,
      "lookup_key": "pro_monthly"
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

list-events

**List events.** Account events of the last 30 days, newest first, optionally only some types (invoice.paid, customer.subscription.deleted, charge.refunded, ...). ending_before returns only events newer than that event id.

Ref `io.b3os/stripe/list-events@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__list-events`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/list-events@1",
          "input": {"types": ["invoice.paid"], "limit": 1},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/list-events@1",
      input: { types: ["invoice.paid"], limit: 1 },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/list-events@1",
        "input": {"types": ["invoice.paid"], "limit": 1},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__list-events",
        "arguments": {"types": ["invoice.paid"], "limit": 1}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__list-events` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: List events (documented response shape, example values). From the bundle's `fixtures/list-events.json`, not a live call.

```json
{
  "data": [
    {
      "id": "evt_1QexampleInvoicePaid",
      "type": "invoice.paid",
      "created": 1792970390,
      "livemode": false,
      "api_version": "2025-09-30.clover",
      "data": {
        "object": {
          "id": "in_1Qexample0001",
          "object": "invoice",
          "amount_paid": 4900,
          "currency": "usd",
          "customer": "cus_Qexample0001",
          "status": "paid"
        }
      }
    }
  ],
  "has_more": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

get-event

**Get event.** One event by id, including the object it describes in data.object. Stripe keeps events for 30 days.

Ref `io.b3os/stripe/get-event@1.0.0` · effect `read` · connection `secret_key` · MCP tool `stripe__get-event`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/stripe/get-event@1",
          "input": {"id": "evt_1QexampleInvoicePaid"},
          "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/stripe/get-event@1",
      input: { id: "evt_1QexampleInvoicePaid" },
      connections: { secret_key: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/stripe/get-event@1",
        "input": {"id": "evt_1QexampleInvoicePaid"},
        "connections": {"secret_key": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "stripe__get-event",
        "arguments": {"id": "evt_1QexampleInvoicePaid"}
      }
    }
    ```

    Expose the pack as tools with `--packs stripe` on the local server or `?packs=stripe` on the remote URL, and the agent calls `stripe__get-event` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get event (documented response shape, example values). From the bundle's `fixtures/get-event.json`, not a live call.

```json
{
  "id": "evt_1QexampleInvoicePaid",
  "type": "invoice.paid",
  "created": 1792970390,
  "livemode": false,
  "api_version": "2025-09-30.clover",
  "data": {
    "object": {
      "id": "in_1Qexample0001",
      "object": "invoice",
      "amount_paid": 4900,
      "currency": "usd",
      "customer": "cus_Qexample0001",
      "status": "paid"
    }
  }
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Stripe rejected the API key. |
| `forbidden` | 403 | no | built from the service's response |
| `rate_limited` | 429 | yes | Stripe rate limit reached; retry with backoff. |
| `invalid_request` | 400 | no | built from the service's response |

## Triggers

event (trigger)

**Stripe event.** Fires once per new Stripe event whose type is in the subscription's types (wildcards like invoice.* work, * for all), checked every 30 seconds by default from the events list. No webhook endpoint is created in your account. The first check records the latest event and emits nothing.

Ref `io.b3os/stripe/event@1.0.0` · poll of `list-events`, every 30 s by default (at least 10 s) · connection `secret_key`

| `with` key | Required | Description |
|---|---|---|
| `types` | yes | Event types, for example invoice.paid, or * for all. |

In a routine:

```yaml
triggers:
  - type: action
    id: event
    uses: io.b3os/stripe/event@1
    with:
      types:
        - invoice.paid
    connections:
      secret_key: conn_01m5t6cbgdjs1ketgcqwa2sne8
```

Event, labeled `fixture`: the first item of `list-events`'s fixture fixtures/list-events.json (List events (documented response shape, example values)) through the trigger's event mapping. A routine reads it as `trigger.data`; its fields are `id`, `type`, `created`, `livemode`, `api_version`, `data`.

```json
{
  "id": "evt_1QexampleInvoicePaid",
  "type": "invoice.paid",
  "created": 1792970390,
  "livemode": false,
  "api_version": "2025-09-30.clover",
  "data": {
    "object": {
      "id": "in_1Qexample0001",
      "object": "invoice",
      "amount_paid": 4900,
      "currency": "usd",
      "customer": "cus_Qexample0001",
      "status": "paid"
    }
  }
}
```

webhook-event (trigger)

**Stripe event (webhook).** Fires as Stripe delivers events to a webhook endpoint you add in the Stripe Dashboard (Developers, Webhooks) with this subscription's URL; paste that endpoint's signing secret (whsec_...) when you create the subscription. Every delivery's Stripe-Signature is verified and must be at most 5 minutes old. Only the types you list (or * for all) and types under the prefixes you list (customer.subscription. for every subscription event) are emitted. Faster than the polled event trigger; the pack itself still never writes to Stripe.

Ref `io.b3os/stripe/webhook-event@1.0.0` · webhook, signature scheme `stripe` with a signing secret you bind as `webhook_secret` · connection `webhook_secret`

| `with` key | Required | Description |
|---|---|---|
| `types` | no | Event types to emit, for example invoice.paid, or * for all. Default `[]`. |
| `type_prefixes` | no | Also emit every type starting with one of these, for example customer.subscription. or invoice. Default `[]`. |

In a routine:

```yaml
triggers:
  - type: action
    id: webhook_event
    uses: io.b3os/stripe/webhook-event@1
    with:
      types:
        - invoice.paid
      type_prefixes:
        - customer.subscription.
    connections:
      webhook_secret: conn_01m5t6cbgdjs1ketgcqwa2sne8
```

Event, labeled `fixture`: the recorded delivery in fixtures/webhook-event-invoice-paid.json (Stripe event (webhook) (delivery signed with a throwaway test secret)). A routine reads it as `trigger.data`; its fields are `id`, `type`, `created`, `livemode`, `api_version`, `data`.

```json
{
  "id": "evt_1QexampleInvoicePaid",
  "type": "invoice.paid",
  "created": 1792970390,
  "livemode": false,
  "api_version": "2025-09-30.clover",
  "data": {
    "object": {
      "id": "in_1Qexample0001",
      "object": "invoice",
      "amount_paid": 4900,
      "currency": "usd",
      "customer": "cus_Qexample0001",
      "status": "paid"
    }
  }
}
```