buyerProfileId when creating a checkout. Without one the agent has no address, and on
most merchants that is where the run stops.
Create
Response (201)
Fields
Every field is optional — the API will happily store{} — but the agent can only fill what
you gave it. A field it does not recognise is a different matter: the body is strict, so a typo is
a 400 rather than a stored profile missing the thing you thought you set.
string
Yours, for your own bookkeeping. Never sent to a merchant.
string
Your own id for the end user this profile is. Optional, 1 to 200 characters, opaque to us,
never sent to a merchant. Set it and an API key bound to that subject sees this profile while
no other end user’s key can — see End-user isolation.It comes back as
null on an untagged profile, and it cannot be changed after creation:
PATCH with subject is a 400, not a silent no-op. Decide before you create. "" is a 400
as well — send a real id or omit the field.object
{ first, last }. Used for the merchant’s name fields, and as the cardholder name at the
payment step — which is why the card action never asks for one.object
{ email, phone }. email is what order confirmations go to; most checkouts refuse to
proceed without it. phone is required by a fair number of merchants, particularly
delivery.object
{ addressLines, locality, administrativeAreaCode, postalCode, countryCode }.addressLines— array of strings. Only the first line is filled on the Shopify tier; a second line is stored but will not be typed. If an apartment number matters, put it on line one.locality— city / town.administrativeAreaCode— state / province. Send the short code (KY,ON) — the code is tried first, then the full name as a visible label.postalCodecountryCode— ISO 3166-1 alpha-2. Filled before the state, because changing country repopulates the province list and would wipe a state chosen first.
Read
List → 200
nextCursor back as ?cursor= for the next
page; nextCursor: null means you have them all. limit defaults to 20 and caps at 100.
Update
PATCH replaces a document wholesale
This is the one thing to get right.name, contact and shipping are each stored as a
single JSON document, and PATCH is partial at the top level only:
- Omit a key and that document is left exactly as it was.
- Supply a key and its document is replaced entirely. Fields you did not mention are gone, not inherited.
- An empty body is a
400 No fields to update, not a no-op that quietly succeeds. subjectis rejected, not ignored — a400with anunrecognized_keysissue. A profile cannot be reassigned to a different end user, and a caller attempting it should be told so rather than getting a200and a profile that has not moved. See End-user isolation.- Send
"name": nullto clear a document outright — that is how you remove an address you no longer want us holding, short of deleting the whole profile."name": {}stores an empty object instead, which is a different thing.
buyerProfileId, never a copy
of the address. Resolve that id after an update and you get the current address, not the one
the parcel actually went to. If shipped-to addresses matter to you — and for anything with a
refund or dispute process they do — record the address yourself at creation time rather than
resolving the reference later.
Delete
Response (200)
Checkouts survive
A checkout that referenced the profile keeps existing, with its
buyerProfileId reference
set to null. Purchase history outlives the identity, so your books still balance and the
deleted person is no longer in them.Buyer sessions cascade
Stored merchant logins for that profile are deleted with it. That is the point of deleting,
not a side effect: leaving a live merchant session behind for a buyer you just erased is
the opposite of what was asked for.
404 Profile not found
covers both “no such id” and “another tenant’s” — a second delete of the same profile is a
404, so treat that as success if you are retrying.
A run currently in flight against a deleted profile does not stop. It already loaded the
address it needed; the reference simply nulls out. Cancel the checkout too if the point is that
nothing more should be shipped.
Profiles and stored merchant sessions
A buyer profile is also the identity that buyer sessions hang off. When a run logs into a merchant with credentials you supplied, the resulting cookies are stored against(tenant, buyerProfileId, merchantDomain) — so the next checkout for that profile
at that merchant starts logged in.
That means the profile id is not just an address book entry. Reusing one profile across
unrelated end users would share their merchant logins. One profile per end user.
If you serve many end users, say which one each profile belongs to: set subject at creation
and issue your agent a key bound to it. That turns “one profile per end user” from a convention
you maintain into a fence the API enforces — a key for one buyer cannot read, patch, delete or
ship to another’s profile, and cannot list them either.
The fence holds from your admin key too, which is where it matters for stored logins: a checkout
tagged subject: "user_a91f" cannot be pointed at a profile tagged for someone else, so a run can
never write one person’s merchant session onto another person’s profile. Naming both is a 403. See
End-user isolation.