---
title: "Mint a one-time Stripe-hosted onboarding link"
method: POST
path: "/projects/v1/{project_id}/stripe/onboarding-links"
tags: ["Projects"]
---

# Mint a one-time Stripe-hosted onboarding link

`POST /projects/v1/{project_id}/stripe/onboarding-links`

## Request

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

Creates a Stripe Account Link of kind account_onboarding for the organization's account (it also collects any requirement Stripe lists after onboarding completed; Stripe refuses account_update links for accounts with Stripe Dashboard access, which every account here has). return_url and refresh_url must be HTTPS on one of the project's own hosts (managed subdomains, branch hosts, verified custom domains) or the Run402 console; http://localhost only for a test-mode account; anything else is 422 STRIPE_RETURN_URL_NOT_ALLOWED with details.field and details.allowed_hosts. Omitted URLs default to the console's account page. The url is one-time and expires in minutes; it is never logged, stored, or returned by any later read. Hand it to the account holder inside your own authenticated page; never email it. 403 STRIPE_ACCOUNT_REQUIRED when the organization has no account. Behind the lifecycle gate.

## Path parameters

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

## Headers

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

## Request body

- StripeOnboardingLinkRequest
  - `return_url` string, uri: Where Stripe sends the account holder after the flow. HTTPS on one of the project's own hosts or the console; defaults to the console's account page.
  - `refresh_url` string, uri: Where Stripe sends them when the link expired or was used; same rule. Your page should mint a new link.

## Response `201`

The one-time link.

- 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

- `403`: STRIPE_ACCOUNT_REQUIRED, not authorized, or the lifecycle gate.
- `422`: STRIPE_RETURN_URL_NOT_ALLOWED (details.field, details.allowed_hosts).
- `502`: STRIPE_UPSTREAM_ERROR.
- `503`: STRIPE_CONNECT_UNAVAILABLE.

---

[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)
