Skip to Content
Passage ConnectAPI ReferenceCreate Link

Create Link

Create a new link intent for account connection.

Request

POST /v1/links

Headers

HeaderValue
AuthorizationBearer YOUR_API_KEY
Content-Typeapplication/json

Body

FieldTypeRequiredDescription
integrationIdstringYesIntegration identifier (e.g., tmobile, att, verizon, ubereats)
operationsarrayYesArray of operations to execute sequentially (see below)
webhookUrlstringNoURL to receive completion webhook (must be a valid URL)
returnUrlstringNoURL to redirect the user after the session completes — supports https:// and custom app schemes (e.g., myapp://callback)
externalUserIdstringNoYour identifier for the user
debugbooleanNoEnable debug mode for this link
expiresInintegerNoCustom link expiry in seconds (default: 4 hours)

Each item in operations:

FieldTypeRequiredDescription
resourcestringYesResource to access (e.g., paymentMethod, mobileBillingStatement, orderHistory)
actionstringYesOperation to perform (read or write)
argumentsobjectNoOperation arguments — validated against the resource’s schema (see List Providers)

Example

{ "integrationId": "tmobile", "operations": [ { "resource": "paymentMethod", "action": "read" }, { "resource": "paymentMethod", "action": "write", "arguments": { "cardNumber": "4111111111111111", "expirationDate": "12/28", "cvv": "123", "nameOnCard": "John Doe", "billingZip": "10001" } } ], "webhookUrl": "https://your-server.com/webhook", "returnUrl": "https://your-app.com/done" }

Operations run sequentially in a single session — the user only logs in once.

Response

201 Created

{ "linkId": "link_abc123", "claimCode": "clm_xxx", "integrationId": "tmobile", "operations": [ { "resource": "paymentMethod", "action": "read" }, { "resource": "paymentMethod", "action": "write" } ], "status": "pending", "appClipUrl": "https://appclip.example.com/link_abc123?code=clm_xxx", "returnUrl": "https://your-app.com/done?linkId=link_abc123", "expiresAt": 1704081600000, "createdAt": 1704067200000 }

400 Bad Request

Returned when:

  • Required fields are missing or have wrong types
  • The operations array is empty
  • The webhookUrl is not a valid URL
  • The returnUrl is not a valid URL or app scheme
  • The expiresIn is not a positive integer
  • Any integrationId + resource + action combination is not valid
  • The arguments for any operation do not match the resource’s schema

Validation errors include structured details:

{ "error": "Validation failed", "issues": [{ "path": "webhookUrl", "message": "must be a valid URL" }] }

Notes

  • Creates a link record only — no session is spawned until the link is claimed
  • The appClipUrl contains the claim code and is passed to the client SDK to initiate the flow
  • Links expire after 4 hours by default, or after expiresIn seconds if specified
  • Use GET /v1/providers to discover valid integration/resource/action combinations and argument schemas
  • All operations execute sequentially in a single session — the user authenticates once
  • If any operation fails the entire link fails; partial results are not persisted
  • For single-operation links, the result is flat (e.g., { billing: [...] }); for multiple operations, results are wrapped: { operations: [{ resource, action, data }, ...] }
Last updated on