Skip to main content
POST
Add a signer to a customer's wallets

Authorizations

x-api-key
string
header
required

Headers

Idempotency-Key
string
required

Caller-generated unique key that lets the server safely replay this request. The original response is returned for 30 days on any retry with the same key from the same organization. Required on every state-changing money-moving or resource-creating POST.

Required string length: 1 - 128
Pattern: ^[A-Za-z0-9_.:-]{1,128}$
Example:

"01J7B3K2X9M8N5P6Q7R8S9T0V1"

Path Parameters

customerId
string
required
Example:

"cus_1A2b3C4d5E6f7G8h9I0jKl"

Body

application/json
email
string<email>
required

Email address of the signer to add

Pattern: ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
Example:

"signer@example.com"

name
string

Display name of the signer

Example:

"Jane Doe"

role
enum<string>

admin = root-quorum member + signing-quorum member; signer = signing-quorum only

Available options:
admin,
signer
credentialType
enum<string>

How this signer will stamp. api_key requires publicKey.

Available options:
passkey,
api_key
publicKey
string

Machine-signer P-256 compressed public key (33 bytes, 02/03 prefix + 64 hex chars, optional 0x prefix). Required when credentialType=api_key.

Pattern: ^(?:0x)?(?:02|03)[0-9a-fA-F]{64}$
Example:

"02a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"

Response

id
string
required

Unique wallet signer identifier

Pattern: ^wsg_[0-9A-Za-z]{22}$
email
string
required

Signer's email address

Example:

"signer@example.com"

name
string | null
required

Signer's display name

Example:

"Jane Doe"

role
enum<string>
required

admin = root-quorum member + signing-quorum member; signer = signing-quorum only

Available options:
admin,
signer
credentialType
enum<string>
required

How this signer stamps requests

Available options:
passkey,
api_key
passkeyCount
integer
required

Number of passkeys enrolled for this signer

Required range: 0 <= x <= 9007199254740991
Example:

0

status
enum<string>
required

Current signer status

Available options:
pending_activation,
activating,
active,
pending_removal,
removed,
error
createdAt
string<date-time>
required

Timestamp when the signer was created

Example:

"2026-01-15T09:30:00.000Z"

updatedAt
string<date-time>
required

Timestamp when the signer was last updated

Example:

"2026-01-15T09:30:00.000Z"

verificationUrl
string | null
required

Synchronous URL for this add, or null when none applies. Read urlAudience to know who it is for before delivering it — a passkey add returns the signer's enrollment link, an api_key add pending approval returns a customer admin's co-stamp link. On a live roster a "signer" link is the FIRST of two links, not full self-service: after the signer enrolls their passkey the add parks a roster-add ceremony for an admin co-stamp, whose link arrives only on the wallet_ceremony.awaiting_admin_approval webhook (carrying the ceremony's ceremonyId).

Example:

"https://app.conduit.financial/verify/mtQzSU2hdy0DuZ6za2IHIoVDgXzshrFtN38kMULRDFw"

urlAudience
enum<string> | null
required

Audience of verificationUrl: signer = the new signer's credential-enrollment link (deliver to the signer) — on a live roster this is only the first of two links, the second being an admin co-stamp delivered on the wallet_ceremony.awaiting_admin_approval webhook; admin = a customer admin's approval link (deliver to an admin; also delivered via the wallet_ceremony.awaiting_admin_approval webhook); null when there is no URL.

Available options:
signer,
admin
awaitingProvider
enum<boolean>

True only while the parked activity is still resolving at the custody provider — verificationUrl/urlAudience are null here too, but unlike a synchronously-admitted add there is a ceremonyId to track and nothing yet for any human to approve. Absent on every other outcome.

Available options:
true
machineApproval
object

Additional material for a machine (api_key) add that parks for approval on a roster carrying an ACTIVE api_key admin. It is handed back ALONGSIDE verificationUrl (urlAudience: "admin") and the wallet_ceremony.awaiting_admin_approval webhook, which are always present — approve either way. Stamp approvalMaterial with an ACTIVE api_key admin's P-256 key and POST { method: "api_key", credential } to /v2/verifications/{token}/complete (credential is { signedBody, stamp, organizationId } as a nested JSON object; a JSON string of the same is deprecated and will be rejected in a future release) to activate the signer — the same stamp-and-approve step every machine governance ceremony uses. Absent when the roster has no api_key admin to stamp.