---
title: "Connect the organization's Stripe account (or return the one it has)"
method: POST
path: "/projects/v1/{project_id}/stripe/account"
tags: ["Projects"]
---

# Connect the organization's Stripe account (or return the one it has)

`POST /projects/v1/{project_id}/stripe/account`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/projects/v1/{project_id}/stripe/account`
- Auth: one of:
  - HTTP bearer
  - API key in header `SIGN-IN-WITH-X`
  - HTTP bearer
  - HTTP bearer

Creates a Stripe connected account for the project's owning organization under Run402's Stripe Connect platform: full Stripe dashboard, Stripe collects its fees and is liable for its losses, card_payments plus sepa_debit_payments where Stripe offers SEPA Direct Debit. Nothing is prefilled that the body does not carry; Stripe collects the rest during hosted onboarding, which a PERSON completes once at the one-time onboarding.url this response carries while onboarding is incomplete. Idempotent per organization: a second call returns the live account with 200 and creates nothing; the create is a durable intent with a deterministic Stripe idempotency key, so an interrupted request never leaves two accounts. Behind the organization lifecycle gate. Audited. Direct charges only: the organization is the merchant of record, Stripe bills it for processing and dispute fees from its own balance, Run402 takes no application fee (platform_fee_bps 0) and never holds, moves, or refunds the money. Refunds and disputes live in the organization's own Stripe dashboard. 503 STRIPE_CONNECT_UNAVAILABLE when the platform's Stripe configuration is absent or Stripe is unreachable.

## Path parameters

- `project_id` string, required: Run402 project ID. Public IDs are not UUIDs.

## Headers

- `SIGN-IN-WITH-X` string, required

## Request body

- StripeAccountConnectRequest: Optional prefill; Stripe collects whatever is missing during hosted onboarding.
  - `country` string: ISO 3166-1 alpha-2. Defaults to the platform's country; the account holder confirms it during onboarding. Decides whether sepa_debit_payments is requested.
  - `business_type` 'company' | 'individual' | 'non_profit'
  - `business_name` string: The display and registered name.
  - `support_email` string, email: Shown to payers on receipts and bank statements; without it Stripe falls back to the platform's support details.
  - `statement_descriptor` string: What the member's bank statement says. Set it so the statement names the organization, never the platform.
  - `email` string, email: The account's contact email (Stripe's own communications go here).

## Response `200`

The organization already has a live account.

- StripeAccountConnectResponse
  - `org_id` string, uuid, required
  - `scope` 'organization', required
  - `account_id` string, nullable, required: The Stripe account id (acct_…); null only while the create is still being confirmed.
  - `status` 'creating' | 'onboarding' | 'active' | 'restricted' | 'disconnected', required
  - `livemode` boolean
  - `charges_enabled` boolean, required
  - `payouts_enabled` boolean, required
  - `details_submitted` boolean, required
  - `requirements` object, required
    - `currently_due` string[]
    - `past_due` string[]
    - `eventually_due` string[]
    - `disabled_reason` string, nullable
  - `capabilities` object, required: Stripe capability statuses by name (card_payments, sepa_debit_payments: active, pending, inactive, unrequested).
  - `country` string, nullable
  - `default_currency` string, nullable
  - `dashboard` 'full', required
  - `custody` 'organization', required
  - `platform_fee_bps` 0, required
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `disconnected_at` string, date-time, nullable
  - `next_actions` NextAction[], required
    - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
    - `method` string
    - `path` string
    - `auth` string
    - `why` string
    - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
    - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.
  - `onboarding` StripeOnboardingLink
    - `url` string, uri, required: One-time; hand it to the account holder inside your authenticated page.
    - `expires_at` string, date-time, required
    - `kind` 'account_onboarding', required
    - `account_id` string
    - `next_actions` NextAction[]
      - `type` string, required: Advisory machine-readable action type such as retry, authenticate, submit_payment, fund_wallet, renew_tier, check_usage, resume_deploy, edit_request, edit_migration, contact_support, upgrade_client, poll (poll the project events feed — appended when the envelope carries a correlated_platform_incident), or hand_to_member (on a commit/promote response that just activated a public site: show the human urls.site and urls.console, relay Run402's offer to promote the build on @run402com, and ask yes or no — see `credited_as` below).
      - `method` string
      - `path` string
      - `auth` string
      - `why` string
      - `credited_as` string, nullable: `hand_to_member` only. The caller's own live presence name in the project's default room, else that room's most recently active live presence, else `null` — in which case `why` tells the agent that joining the room with a name (`run402 rooms join --name ...`) is how the promotion credits it.
      - `body` object: `hand_to_member` only. A ready-to-send `POST /feedback/v1` template: `{ project_id, message: "promote: yes", handle? }`.

## Other responses

- `201`: Account created; onboarding carries the one-time hosted-onboarding link.
- `403`: Wrong credential class, a service_key of another project, a principal without project.stripe.manage, or the organization's lifecycle gate.
- `422`: VALIDATION_FAILED naming the field (country, business_type, business_name, support_email, statement_descriptor, email).
- `502`: STRIPE_UPSTREAM_ERROR: Stripe refused the create; details.code and details.param name why (for example account_create_activation_required).
- `503`: STRIPE_CONNECT_UNAVAILABLE (Retry-After).

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
