Create a buyer profile
Every field is optional — {} is a valid profile — but the agent can only fill what you gave it. Values are stored and typed exactly as sent: no normalisation, no address validation, no correction.
One profile per end user. A profile is the identity that stored merchant sessions hang off, so reusing one across unrelated buyers would share their merchant logins.
Requires the buyer-profiles.write scope.
Set subject to say which of your end users this profile is for. A key bound to that subject can then reach it and no other end user’s key can.
Authorizations
Authorization: Bearer ck_test_… or ck_live_…. There is no other auth scheme — no query-string keys, no request signing, no OAuth.
Body
Every field is optional — {} is a valid profile — but the agent can only fill what you gave it.
The top level is strict: an unrecognised field is a 400 with an unrecognized_keys issue, not a field the server drops for you. The field most worth misspelling here is subject, and a 201 carrying an untagged row is an isolation control that failed open on a typo. The nested name, contact and shipping objects are not strict. PATCH is strict in the same way.
Yours, for bookkeeping. Never sent to a merchant.
Your own opaque id for one of your end users. 1 to 200 characters after trimming; never parsed, never validated against anything, and never sent to a merchant. An empty or whitespace-only value is a 400 — a subject that means nothing reads as isolation you do not have.
On a key bound to a subject this is filled in for you: omit it and the row is stamped with the key's subject, name a different one and the request is a 403. On a tenant-wide key it is how a row gets tagged in the first place.
Create-only. A profile cannot be reassigned to another end user afterwards: PATCH with subject is a 400.
1 - 200"user_a91f"
Also used as the cardholder name at the payment step, which is why the card action never asks for one.
Response
Created. Omitted sub-objects come back as null, not {}.
Your own id for the end user this profile belongs to, or null when it is not tagged to one. Always present — unlike a checkout, which omits the field entirely. Fixed at creation.
"user_a91f"
null when never supplied — not {}.