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

# Stripe

> Connect Stripe to Serval with a secret API key so workflows can look up and manage customers, payments, invoices, subscriptions, and payouts.

## About Stripe

Stripe is a payments and financial infrastructure platform covering customers, charges, payment intents, invoices, subscriptions, refunds, payouts, products, prices, disputes, balance, and connected accounts. The Serval Stripe integration connects with a single secret API key and gives your workflows access to the full Stripe API - the integration can do exactly what the key you provide is allowed to do. Serval only ever sends the key to one host for this integration: api.stripe.com.

**Authentication:** API key (a Stripe secret key or, recommended, a restricted key). There is no OAuth or sign-in flow.

**Data sync:** On demand only. There is no background sync, no webhooks, and no preinstalled workflows - Serval talks to Stripe only when a workflow runs or a health check executes.

## What the Stripe integration enables

| Capability                            | Description                                                                                                                                                                                                                                                                                                 |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Full Stripe API access from workflows | Workflows can call the entire Stripe API - customers, charges, payment intents, invoices, subscriptions, refunds, payouts, products, prices, disputes, balance, balance transactions, billing, and connected accounts. Reads and writes are both supported, limited only by what the connected key permits. |
| Look up payments and customers        | Read customers, charges, payment intents, invoices, subscriptions, refunds, and payouts as part of a workflow.                                                                                                                                                                                              |
| Check account and balance             | Retrieve your Stripe account status (including whether charges and payouts are enabled) and review balance and balance transaction activity.                                                                                                                                                                |
| Create and update Stripe records      | Create, update, and delete Stripe objects (customers, subscriptions, refunds, and more) from workflows, within the permissions of the connected key.                                                                                                                                                        |
| Paginated list handling               | Stripe returns list results one page at a time; workflows can page through large lists until Stripe reports there are no more results.                                                                                                                                                                      |

Anything defined in the [Stripe API](https://docs.stripe.com/api) can be accessed through Serval.

## Get your credentials

You need one Stripe API key: either a standard secret key (starts with `sk_test_` or `sk_live_`) or - recommended for least privilege - a restricted key (starts with `rk_test_` or `rk_live_`) that grants only the resources your workflows need. Stripe's official guide is at [docs.stripe.com/keys](https://docs.stripe.com/keys), and details on how keys authenticate are in the [Stripe API authentication docs](https://docs.stripe.com/api/authentication).

<Steps>
  <Step title="Log in to the Stripe Dashboard">
    Go to [dashboard.stripe.com](https://dashboard.stripe.com) and sign in.
  </Step>

  <Step title="Open the API keys page">
    Navigate to Developers, then API keys, or go directly to [dashboard.stripe.com/apikeys](https://dashboard.stripe.com/apikeys).
  </Step>

  <Step title="Create a key">
    Click **Create secret key** (or **Create restricted key** to limit permissions). Complete the email or SMS verification if prompted, and give the key a recognizable name such as "Serval Integration".
  </Step>

  <Step title="If using a restricted key, grant the minimum permissions">
    Serval's four health checks read your account information, customers, charges, and balance transactions, so grant read access covering those resources if you want every check to pass. Add read and write access on any other resources your workflows will touch.
  </Step>

  <Step title="Copy the key immediately">
    Stripe shows the key only once. Copy it before leaving the page.
  </Step>
</Steps>

<Warning>
  Stripe keys are environment-specific. A `sk_test_` key sees only test data and a `sk_live_` key sees only live data. Create the key in the environment your workflows should operate on.
</Warning>

<Tip>
  A standard secret key grants full account access. If you only need Serval to read payment data, a restricted key keeps the blast radius small.
</Tip>

## Connect in Serval

<Steps>
  <Step title="Open the Stripe connect form">
    Add a new Stripe connection from your Serval integrations page, or from an application's API integration setup.
  </Step>

  <Step title="Paste your key into the API Key field">
    The form has a single field, **API Key** (a password-type input with the helper text "Your Stripe API key (starts with sk\_test\_ or sk\_live\_)"). Paste the full secret or restricted key you created. The field is not marked required, so you will not see an asterisk or a "This field is required" error.
  </Step>

  <Step title="Submit the form">
    Click **Connect Stripe** (or **Submit** if you are connecting through the configure dialog). If saving fails, the application setup form shows "Failed to connect service", while the configure dialog shows "Failed to install integration" (with details appended when available). On success the connection appears as "Stripe", pointed at api.stripe.com.
  </Step>

  <Step title="Check the health check results">
    Serval does not test or format-check the key when you save - a blank, mistyped, or truncated key saves without error. When you connect from an application's setup form, Serval automatically queues the enabled health checks right after the connection saves; review their results, or run them yourself with the **Run** button on the connection's health check section (see below).
  </Step>
</Steps>

<Tip>
  After saving, the key is displayed masked - bullet characters plus its last 4 characters. To rotate it later, click **Replace** next to the masked value (or the pencil icon on the connection's settings form) and paste the complete new key into the "Enter new value" box. Saving an update with the key field untouched or blank keeps your existing stored key, so you never need to re-enter the key just to edit the connection. If an update fails, Serval shows "Failed to update integration:" followed by details, "Failed to update configuration", or "Failed to save configuration. Please try again.", depending on which form you used.
</Tip>

## Verifying the connection

The Stripe integration ships four health checks. Run them after connecting and after rotating the key.

| Health check                     | What it verifies                                                                                                         | Success message                                                                 | Failure message                                                                                             |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Get Stripe Account               | The key is valid and Serval can retrieve your account information (account ID, whether charges and payouts are enabled). | "Successfully connected to Stripe account (ID: \[account ID])"                  | "Unable to retrieve Stripe account info. Please verify your API key is valid."                              |
| List Stripe Customers            | The key can list customers (samples up to 10).                                                                           | "Successfully listed customers from Stripe (sample size: \[number])"            | "Unable to list customers from Stripe. Please verify your API key has the required permissions."            |
| List Stripe Charges              | The key can list charges (samples up to 10).                                                                             | "Successfully listed charges from Stripe (sample size: \[number])"              | "Unable to list charges from Stripe. Please verify your API key has the required permissions."              |
| List Stripe Balance Transactions | The key can list balance transactions (samples up to 10).                                                                | "Successfully listed balance transactions from Stripe (sample size: \[number])" | "Unable to list balance transactions from Stripe. Please verify your API key has the required permissions." |

<Tip>
  If "Get Stripe Account" passes but the list checks fail, your key is valid but restricted: it is missing read access to customers, charges, or balance transactions. Add those read permissions to the restricted key, or treat those specific failures as expected if your workflows never touch those resources.
</Tip>

## Gotchas and troubleshooting

<AccordionGroup>
  <Accordion title="A bad key saves without any error">
    Neither the form nor Serval validates the key's presence or format at connect time. A blank, truncated, or wrong-environment key saves successfully and only shows up later as failing health checks. Check the health check results right after connecting - at minimum "Get Stripe Account".
  </Accordion>

  <Accordion title="Rotating the API key">
    Click **Replace** next to the masked value (configure dialog) or the pencil icon (settings form) and paste the complete new key into the "Enter new value" box. Leaving the field untouched or blank when saving an update keeps the previously stored key, so edits to the connection never require re-entering a working key. After rotating, run the health checks to confirm the new key works.
  </Accordion>

  <Accordion title="Restricted keys can fail health checks while workflows still work">
    The four health checks read account info, customers, charges, and balance transactions. A restricted key missing read access to any of these reports "Please verify your API key has the required permissions" even if your actual workflows never touch those resources. Either grant the read permissions or treat those specific failures as expected.
  </Accordion>

  <Accordion title="Workflows return test data instead of live data (or vice versa)">
    Test mode and live mode are separate worlds in Stripe. A `sk_test_` key only sees test data; a `sk_live_` key only sees live data. If workflows return data from the wrong environment, reconnect with the key for the intended environment.
  </Accordion>

  <Accordion title="The key is only ever sent to api.stripe.com">
    Serval attaches your Stripe API key only to requests bound for Stripe's official API host (api.stripe.com). Custom workflow steps must use standard Stripe API calls; a request to any other host will not carry the credential and will fail to authenticate.
  </Accordion>

  <Accordion title="Lists come back one page at a time (for workflow builders)">
    Stripe wraps list results in a page that includes a `has_more` flag, and the next page is requested with `starting_after` set to the last item's ID. Workflows that need a complete list must keep paging until `has_more` is false. Related objects can be included in a response using Stripe's `expand[]` query option. See the [Stripe API reference](https://docs.stripe.com/api) for details, and be aware of [Stripe's rate limits](https://docs.stripe.com/rate-limits) when paging through large lists.
  </Accordion>
</AccordionGroup>

***

Need help? Contact **[support@serval.com](mailto:support@serval.com)** for assistance with your Stripe integration.
