Update an existing contact identified by its unique id.
Include one or more fields to change. Field updates and consent changes
can be combined in a single request.
email and phone_number can only be set when the existing value is
null. Once populated, they cannot be changed or cleared.
Consent fields: email_consent, sms_consent. Use these to subscribe,
unsubscribe, or otherwise manage a contact’s marketing consent.
When sms_consent is set to subscribed and the contact transitions to
a confirmed opt-in state, Privy automatically sends a TCPA-required
welcome SMS. Pass send_welcome_sms: false to suppress this message if
you have already collected consent outside of Privy.
Target a subaccount instead of the main connected account.
Pass a subaccount id from get_account's subaccounts list. Only direct subaccounts
of the connected account are reachable — omit this for the main account itself.
The contact's unique identifier (returned as id in contact responses). Ids are opaque cus_-prefixed strings — a numeric id from a Privy dashboard URL is not a valid API id and will 404; list contacts, or look the contact up by ?email= or ?phone_number=, instead.
Body
application/json
Include one or more fields to update. The contact is identified
by the id path parameter. Field updates and consent changes can be
combined in a single request.
Sets the contact's phone number in E.164 format. Only allowed when
the contact's current phone_number is null; once populated,
phone_number is immutable.
Update the contact's email marketing consent.
compliance_suppressed is read-only — any write to this field on a
compliance-suppressed contact returns 422. The contact's other
fields, and its sms_consent, stay editable.
For merchant-suppressed contacts, writing any consent value first
unsuppresses, then applies the requested transition (e.g.
subscribed unsuppresses then subscribes).
Update the contact's SMS marketing consent. pending is read-only.
subscribed, single_opt_in, and unsubscribed require the contact
to have a phone number. single_opt_in is idempotent when the contact
is already in that state, and returns 422 from terminal states
(pending, subscribed, or unsubscribed).
When sms_consent is set to subscribed and the contact transitions
to a confirmed SMS opt-in state, Privy sends a TCPA-required welcome
SMS. Set to false to suppress this message when you have already
collected consent outside of Privy.
A contact in your Privy account: identity, marketing consent per channel, tags, and custom
fields. Email and SMS consent are tracked independently — a contact who opts out of one
keeps whatever consent they had for the other.
Show child attributes
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Privy Knowledge Base","colors":{"primary":"#254E5A","light":"#E3E32B","dark":"#254E5A"},"logo":{"light":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/light.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=36a01db426b7c94fac423778765cd517","dark":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/dark.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=24576b53a928bf065f4a636ab8dc3431"},"favicon":"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/favicon.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=9fee6eb5a3c74b929294365e07a3f01d","background":{"color":{"light":"#FFF","dark":"#0D1D23"}},"navbar":{"links":[{"href":"https://www.privy.com/pricing","label":"Pricing"},{"href":"mailto:support@privy.com","label":"Contact Support"}],"primary":{"type":"button","label":"Login","href":"https://dashboard.privy.com"}},"footer":{"socials":{"x":"https://x.com/privy","linkedin":"https://www.linkedin.com/company/privy"}},"seo":{"indexing":"all"},"fonts":{"heading":{"family":"Matter","weight":650,"source":"https://public-assets.privy.com/MatterStandard-VF.woff2","format":"woff2"},"body":{"family":"Matter","weight":400,"source":"https://public-assets.privy.com/MatterStandard-VF.woff2","format":"woff2"}},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"privy","hasAudioNarration":false,"actualSubdomain":"privy","customDomains":["help.privy.com"],"gitSource":{"type":"github","owner":"privy","repo":"mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"feedback":{"thumbs":true,"issues":true,"edits":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af26d3d77039a55c1b053dc","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"Learn","count":275},{"language":"default","tag":"Developer","count":49},{"language":"default","tag":"Integrations","count":30},{"language":"default","tag":"Strategy Guides","count":24},{"language":"default","tag":"Flows","count":18},{"language":"default","tag":"Account + Billing","count":18},{"language":"default","tag":"Contacts","count":17},{"language":"default","tag":"Displays","count":15},{"language":"default","tag":"Deliverability","count":11},{"language":"default","tag":"Content","count":10}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":"@font-face{font-family:\"Matter\";src:url(\"https://public-assets.privy.com/MatterStandard-VF.woff2\") format(\"woff2\");font-display:swap;font-style:normal;font-weight:600}.mdx-content strong,.mdx-content b{font-weight:600}.mdx-content em,.mdx-content i{font-style:italic}"}],"page":{"pagePath":"docs/api-reference/update-contact","slug":"/docs/api-reference/update-contact","pageMetadata":{"title":"Update a contact","openapi":"openapi/privy-api.yaml PATCH /contacts/{id}","description":"Update an existing contact identified by its unique `id`.\nInclude one or more fields to change. Field updates and consent changes\ncan be combined in a single request.\n\nMutable fields: `first_name`, `last_name`, `email`, `phone_number`, `tags`, `custom_fields`.\n\n`email` and `phone_number` can only be set when the existing value is\n`null`. Once populated, they cannot be changed or cleared.\n\nConsent fields: `email_consent`, `sms_consent`. Use these to subscribe,\nunsubscribe, or otherwise manage a contact's marketing consent.\n\nWhen `sms_consent` is set to `subscribed` and the contact transitions to\na confirmed opt-in state, Privy automatically sends a TCPA-required\nwelcome SMS. Pass `send_welcome_sms: false` to suppress this message if\nyou have already collected consent outside of Privy.\n\n**Required scope:** `contacts_write`\n","href":"/docs/api-reference/update-contact"},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Update an existing contact identified by its unique \", _jsx(_components.code, {\n children: \"id\"\n }), \".\\nInclude one or more fields to change. Field updates and consent changes\\ncan be combined in a single request.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Mutable fields: \", _jsx(_components.code, {\n children: \"first_name\"\n }), \", \", _jsx(_components.code, {\n children: \"last_name\"\n }), \", \", _jsx(_components.code, {\n children: \"email\"\n }), \", \", _jsx(_components.code, {\n children: \"phone_number\"\n }), \", \", _jsx(_components.code, {\n children: \"tags\"\n }), \", \", _jsx(_components.code, {\n children: \"custom_fields\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"email\"\n }), \" and \", _jsx(_components.code, {\n children: \"phone_number\"\n }), \" can only be set when the existing value is\\n\", _jsx(_components.code, {\n children: \"null\"\n }), \". Once populated, they cannot be changed or cleared.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Consent fields: \", _jsx(_components.code, {\n children: \"email_consent\"\n }), \", \", _jsx(_components.code, {\n children: \"sms_consent\"\n }), \". Use these to subscribe,\\nunsubscribe, or otherwise manage a contact’s marketing consent.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"When \", _jsx(_components.code, {\n children: \"sms_consent\"\n }), \" is set to \", _jsx(_components.code, {\n children: \"subscribed\"\n }), \" and the contact transitions to\\na confirmed opt-in state, Privy automatically sends a TCPA-required\\nwelcome SMS. Pass \", _jsx(_components.code, {\n children: \"send_welcome_sms: false\"\n }), \" to suppress this message if\\nyou have already collected consent outside of Privy.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Required scope:\"\n }), \" \", _jsx(_components.code, {\n children: \"contacts_write\"\n })]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Update a contact","openapi":"openapi/privy-api.yaml PATCH /contacts/{id}","description":"Update an existing contact identified by its unique `id`.\nInclude one or more fields to change. Field updates and consent changes\ncan be combined in a single request.\n\nMutable fields: `first_name`, `last_name`, `email`, `phone_number`, `tags`, `custom_fields`.\n\n`email` and `phone_number` can only be set when the existing value is\n`null`. Once populated, they cannot be changed or cleared.\n\nConsent fields: `email_consent`, `sms_consent`. Use these to subscribe,\nunsubscribe, or otherwise manage a contact's marketing consent.\n\nWhen `sms_consent` is set to `subscribed` and the contact transitions to\na confirmed opt-in state, Privy automatically sends a TCPA-required\nwelcome SMS. Pass `send_welcome_sms: false` to suppress this message if\nyou have already collected consent outside of Privy.\n\n**Required scope:** `contacts_write`\n","href":"/docs/api-reference/update-contact"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"updateContactById","summary":"Update a contact by ID","description":"Update an existing contact identified by its unique `id`.\nInclude one or more fields to change. Field updates and consent changes\ncan be combined in a single request.\n\nMutable fields: `first_name`, `last_name`, `email`, `phone_number`, `tags`, `custom_fields`.\n\n`email` and `phone_number` can only be set when the existing value is\n`null`. Once populated, they cannot be changed or cleared.\n\nConsent fields: `email_consent`, `sms_consent`. Use these to subscribe,\nunsubscribe, or otherwise manage a contact's marketing consent.\n\nWhen `sms_consent` is set to `subscribed` and the contact transitions to\na confirmed opt-in state, Privy automatically sends a TCPA-required\nwelcome SMS. Pass `send_welcome_sms: false` to suppress this message if\nyou have already collected consent outside of Privy.\n\n**Required scope:** `contacts_write`\n","tags":["Contacts"],"security":["4b026326-17a4-49ca-8669-46bcd53a85a7"],"parameters":["c821e45e-16aa-423f-bb01-488384ee0623","3cf131d9-ecfc-459f-8376-f356df8554da"],"requestBody":"bed7f78f-5d88-42d8-a425-a1f2873439ec","responses":{"200":"3c34c93c-f970-405c-952d-ee0127963cf8","400":"911d0fc5-db27-4d88-a110-2602db31b191","401":"f34e0dbc-cf8c-4e80-b515-f4581952435b","403":"bc01ec0f-6ebb-43f1-bb13-d68145c1915c","404":"b1c338d3-a9cb-46eb-81ab-2b7bfada67d7","422":"0190e31f-de82-4f7e-9bf3-1e6f2afd707a","429":"0c557dbf-a0d7-490f-803b-eef56c8aaca5"},"method":"patch","type":"path","servers":["97f63e03-f020-41b7-a5b9-e312bbfed47d"],"path":"/contacts/{id}","baseUrlOptions":["https://api.privy.com/v1"],"title":"Update a contact by ID","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"c821e45e-16aa-423f-bb01-488384ee0623":{"name":"Privy-Account-Id","in":"header","required":false,"description":"Target a subaccount instead of the main connected account.\nPass a subaccount `id` from get_account's `subaccounts` list. Only direct subaccounts\nof the connected account are reachable — omit this for the main account itself.\n","schema":{"type":"string","isRequired":false,"description":"Target a subaccount instead of the main connected account.\nPass a subaccount `id` from get_account's `subaccounts` list. Only direct subaccounts\nof the connected account are reachable — omit this for the main account itself.\n","uniqueKey":"","typeLabel":"string"},"example":"S1U2B3A4C5C6T7"},"3cf131d9-ecfc-459f-8376-f356df8554da":{"name":"id","in":"path","required":true,"description":"The contact's unique identifier (returned as `id` in contact responses). Ids are opaque `cus_`-prefixed strings — a numeric id from a Privy dashboard URL is not a valid API id and will 404; list contacts, or look the contact up by `?email=` or `?phone_number=`, instead.","schema":{"type":"string","isRequired":true,"description":"The contact's unique identifier (returned as `id` in contact responses). Ids are opaque `cus_`-prefixed strings — a numeric id from a Privy dashboard URL is not a valid API id and will 404; list contacts, or look the contact up by `?email=` or `?phone_number=`, instead.","uniqueKey":"","typeLabel":"string"},"example":"cus_a1b2c3d4e5f6g7h8"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Include one or more fields to update. The contact is identified\nby the `id` path parameter. Field updates and consent changes can be\ncombined in a single request.\n\nMutable fields: `first_name`, `last_name`, `email`, `phone_number`, `tags`, `custom_fields`.\n\n`email` and `phone_number` can only be set when the existing value is\n`null`. Once populated, they cannot be changed or cleared.\n\nConsent fields: `email_consent`, `sms_consent`. Use these to manage a\ncontact's marketing consent instead of the deprecated unsubscribe endpoint.\n","properties":{"first_name":{"type":"string","description":"Updated first name.","example":"Janet","uniqueKey":"first_name","typeLabel":"string"},"last_name":{"type":"string","description":"Updated last name.","example":"Smith","uniqueKey":"last_name","typeLabel":"string"},"email":{"type":"string","format":"email","description":"Sets the contact's email address. Only allowed when the contact's\ncurrent `email` is `null`; once populated, `email` is immutable.\n","example":"janet@example.com","uniqueKey":"email","typeLabel":"string\u003cemail>"},"phone_number":{"type":"string","description":"Sets the contact's phone number in E.164 format. Only allowed when\nthe contact's current `phone_number` is `null`; once populated,\n`phone_number` is immutable.\n","example":"+15551234567","uniqueKey":"phone_number","typeLabel":"string"},"tags":{"type":"array","items":{"type":"string","uniqueKey":"tags.items.[INDEX]","typeLabel":"string"},"description":"Replaces all existing tags.","example":["vip","wholesale"],"uniqueKey":"tags","typeLabel":"string[]"},"custom_fields":{"type":"object","additionalProperties":{"type":"string","uniqueKey":"custom_fields.additionalProperties","typeLabel":"string"},"description":"Replaces all existing custom fields. Must be a flat key-value object.","example":{"loyalty_tier":"platinum"},"uniqueKey":"custom_fields","typeLabel":"object"},"email_consent":{"type":"string","enum":["subscribed","unsubscribed","never_subscribed","suppressed"],"description":"Update the contact's email marketing consent.\n`compliance_suppressed` is read-only — any write to this field on a\ncompliance-suppressed contact returns `422`. The contact's other\nfields, and its `sms_consent`, stay editable.\n\nFor merchant-suppressed contacts, writing any consent value first\nunsuppresses, then applies the requested transition (e.g.\n`subscribed` unsuppresses then subscribes).\n","example":"unsubscribed","uniqueKey":"email_consent","typeLabel":"enum\u003cstring>"},"sms_consent":{"type":"string","enum":["subscribed","unsubscribed","never_subscribed","single_opt_in"],"description":"Update the contact's SMS marketing consent. `pending` is read-only.\n`subscribed`, `single_opt_in`, and `unsubscribed` require the contact\nto have a phone number. `single_opt_in` is idempotent when the contact\nis already in that state, and returns `422` from terminal states\n(`pending`, `subscribed`, or `unsubscribed`).\n","example":"unsubscribed","uniqueKey":"sms_consent","typeLabel":"enum\u003cstring>"},"send_welcome_sms":{"type":"boolean","default":true,"description":"When `sms_consent` is set to `subscribed` and the contact transitions\nto a confirmed SMS opt-in state, Privy sends a TCPA-required welcome\nSMS. Set to `false` to suppress this message when you have already\ncollected consent outside of Privy.\n","example":false,"uniqueKey":"send_welcome_sms","typeLabel":"boolean"}},"uniqueKey":"","typeLabel":"object"},"example":{"first_name":"Janet","tags":["vip","wholesale"],"email_consent":"unsubscribed"},"examples":{"Example":{"title":"Example","value":{"first_name":"Janet","tags":["vip","wholesale"],"email_consent":"unsubscribed"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"3c34c93c-f970-405c-952d-ee0127963cf8":{"description":"Contact updated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"A contact in your Privy account: identity, marketing consent per channel, tags, and custom\nfields. Email and SMS consent are tracked independently — a contact who opts out of one\nkeeps whatever consent they had for the other.\n","properties":{"id":{"type":"string","description":"Stable, unique identifier for the contact. Use this value in `/v1/contacts/{id}` endpoints.","example":"cus_a1b2c3d4e5f6g7h8","uniqueKey":"data.id","typeLabel":"string"},"first_name":{"oneOf":[{"type":"string","example":"Jane","uniqueKey":"data.first_name.oneOf.0","typeLabel":"string"},{"type":"null","example":"Jane","uniqueKey":"data.first_name.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.first_name","typeLabel":"string | null"},"last_name":{"oneOf":[{"type":"string","example":"Doe","uniqueKey":"data.last_name.oneOf.0","typeLabel":"string"},{"type":"null","example":"Doe","uniqueKey":"data.last_name.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.last_name","typeLabel":"string | null"},"email":{"oneOf":[{"type":"string","format":"email","example":"jane@example.com","uniqueKey":"data.email.oneOf.0","typeLabel":"string\u003cemail>"},{"type":"null","format":"email","example":"jane@example.com","uniqueKey":"data.email.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.email","typeLabel":"string\u003cemail> | null"},"email_consent":{"type":"string","enum":["subscribed","unsubscribed","never_subscribed","suppressed","compliance_suppressed"],"description":"The contact's email marketing consent. `subscribed` is the only value that makes a\ncontact mailable; Privy sends no marketing email to any of the other four.\n\n- `subscribed` — the contact has opted in. Covers both explicit consent (they ticked an\n email opt-in box, confirmed a double opt-in, or were subscribed through this API) and\n implicit consent (they gave you their address while buying, or arrived in an approved\n \"subscribed\" import). The two are not distinguished here.\n- `unsubscribed` — the contact opted out, typically through the preferences link in a\n Privy email. A later signup that provides consent resubscribes them.\n- `never_subscribed` — no opt-in and no opt-out on record; shown as \"unset\" in the Privy\n dashboard. This is the usual state for someone who bought without opting in, and for\n an imported contact whose import is still awaiting review.\n- `suppressed` — you suppressed the contact, from the dashboard or by writing\n `suppressed` to this field. Reversible: writing any other consent value unsuppresses\n the contact first, then applies the change you asked for.\n- `compliance_suppressed` — Privy suppressed the address to protect your sending\n reputation: a hard bounce, a spam complaint, a rejected delivery, an address that\n failed Privy's compliance check during an import, or a flow's Suppress Contact action.\n Read-only through this API — a write to this field returns `422`, and a later signup\n does not resubscribe them. Other fields on the contact remain editable.\n","example":"subscribed","uniqueKey":"data.email_consent","typeLabel":"enum\u003cstring>"},"email_consent_at":{"oneOf":[{"type":"string","format":"date-time","description":"When `email_consent` last changed. Null when consent was never set.\n","example":"2025-03-20T14:22:00Z","uniqueKey":"data.email_consent_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When `email_consent` last changed. Null when consent was never set.\n","example":"2025-03-20T14:22:00Z","uniqueKey":"data.email_consent_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.email_consent_at","typeLabel":"string\u003cdate-time> | null"},"phone_number":{"oneOf":[{"type":"string","example":"+15551234567","uniqueKey":"data.phone_number.oneOf.0","typeLabel":"string"},{"type":"null","example":"+15551234567","uniqueKey":"data.phone_number.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.phone_number","typeLabel":"string | null"},"sms_consent":{"type":"string","enum":["subscribed","unsubscribed","never_subscribed","single_opt_in","pending"],"description":"The contact's SMS marketing consent. `subscribed` is the only value that makes a contact\ntextable; Privy sends no marketing text to any of the other four.\n\n- `subscribed` — the contact's SMS opt-in is confirmed. Reached by replying `Y` to a\n double opt-in text, by signing up on a display set to Single Opt-In, by replying\n `START` or `UNSTOP`, by an opt-in recorded through this API, by a CSV import of\n SMS consent, or by a synced consent status from a connected store provider\n (e.g. Shopify). A confirmed opt-in does not record which method produced it:\n Single Opt-In and Double Opt-In displays both land on `subscribed`, so this field\n cannot tell you whether a contact double-opted in.\n- `unsubscribed` — the contact opted out, normally by replying `STOP`. Unlike email\n compliance suppression this is reversible: a new confirmed opt-in subscribes them again.\n- `never_subscribed` — no opt-in and no opt-out on record. Also the value after a\n reset: Privy clears SMS consent to this state when the phone number is removed from\n the contact, when a carrier reports the number as a landline, and when\n `never_subscribed` is written through this API. A contact who completed the SMS step\n of a multi-step display and has not yet replied `Y` also reads `never_subscribed` —\n that flow holds the opt-in off the contact record until it is confirmed — so do not\n read this value as \"Privy never asked\".\n- `single_opt_in` — a transitional pre-confirmation state inside the double opt-in\n flow, and the only pre-confirmation state a display signup can leave a contact in.\n The contact submitted a single-step display whose SMS opt-in method is Double Opt-In\n (Privy's default): the phone number is recorded, consent is not yet confirmed, and\n Privy is about to send the `Reply Y` confirmation text. In the healthy path the\n contact leaves this state within seconds — `pending` once the confirmation text is\n accepted by the carrier, then `subscribed` on the `Y` reply. A contact who stays\n here is one whose confirmation text was never sent (unsupported region, non-mobile\n number, SMS sending disabled on the account) or one written here directly through\n this API, which sends no confirmation text and so has no way forward. Not textable.\n Despite the name this is not the display's Single Opt-In setting — a display set to\n Single Opt-In confirms the contact outright, which reads as `subscribed`.\n- `pending` — Privy sent the double opt-in confirmation text and is waiting for the\n `Y` reply. Only reachable from `single_opt_in`, and only on the single-step display\n flow; the multi-step display flow tracks its awaiting-reply opt-ins outside this\n field. Not textable. Read-only.\n","example":"subscribed","uniqueKey":"data.sms_consent","typeLabel":"enum\u003cstring>"},"sms_consent_at":{"oneOf":[{"type":"string","format":"date-time","description":"When `sms_consent` last changed. Null when consent was never set.","example":"2025-03-20T14:22:00Z","uniqueKey":"data.sms_consent_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","description":"When `sms_consent` last changed. Null when consent was never set.","example":"2025-03-20T14:22:00Z","uniqueKey":"data.sms_consent_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.sms_consent_at","typeLabel":"string\u003cdate-time> | null"},"source":{"oneOf":[{"type":"string","description":"How the contact RECORD was created: an import mechanism (`csv`, `shopify`,\n`mailchimp`, …), a Privy display, or the API. Free-form vocabulary — new\nintegrations add values. This is not signup attribution: a store webhook or\nsync can create the record before the visitor ever signs up on a display, and\na later display signup does not rewrite it. For which display(s) a contact\nsigned up on, read `signups` on `GET /v1/contacts/{id}`.\n","example":"csv","uniqueKey":"data.source.oneOf.0","typeLabel":"string"},{"type":"null","description":"How the contact RECORD was created: an import mechanism (`csv`, `shopify`,\n`mailchimp`, …), a Privy display, or the API. Free-form vocabulary — new\nintegrations add values. This is not signup attribution: a store webhook or\nsync can create the record before the visitor ever signs up on a display, and\na later display signup does not rewrite it. For which display(s) a contact\nsigned up on, read `signups` on `GET /v1/contacts/{id}`.\n","example":"csv","uniqueKey":"data.source.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.source","typeLabel":"string | null"},"source_type":{"oneOf":[{"type":"string","description":"The kind of origin behind `source`. Common values: `import` (arrived in a contact\nimport or store sync), `web` (signed up on a display), `hook` (created by a store\nwebhook — e.g. `source: shopify, source_type: hook` is a contact first seen through\na Shopify order or customer webhook). Same caveat as `source`: describes record\ncreation, not later display signups.\n","example":"import","uniqueKey":"data.source_type.oneOf.0","typeLabel":"string"},{"type":"null","description":"The kind of origin behind `source`. Common values: `import` (arrived in a contact\nimport or store sync), `web` (signed up on a display), `hook` (created by a store\nwebhook — e.g. `source: shopify, source_type: hook` is a contact first seen through\na Shopify order or customer webhook). Same caveat as `source`: describes record\ncreation, not later display signups.\n","example":"import","uniqueKey":"data.source_type.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.source_type","typeLabel":"string | null"},"imported":{"oneOf":[{"type":"boolean","description":"Whether the contact arrived in a contact import.","example":true,"uniqueKey":"data.imported.oneOf.0","typeLabel":"boolean"},{"type":"null","description":"Whether the contact arrived in a contact import.","example":true,"uniqueKey":"data.imported.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.imported","typeLabel":"boolean | null"},"import_ids":{"type":"array","items":{"type":"string","uniqueKey":"data.import_ids.items.[INDEX]","typeLabel":"string"},"description":"The email contact imports that touched this contact, oldest first. SMS consent\nimports are tracked separately and are not referenced here.\n","example":["im_k2R5m8Q"],"uniqueKey":"data.import_ids","typeLabel":"string[]"},"tags":{"type":"array","items":{"type":"string","uniqueKey":"data.tags.items.[INDEX]","typeLabel":"string"},"description":"The contact's Privy tags — free-form labels you define, with no fixed vocabulary. Privy\nlower-cases each name, trims surrounding whitespace, and drops duplicates on save, so tags\nalways read back normalized. A name Privy has not seen for the account before is\nregistered automatically and becomes available for contact filtering, segment conditions,\nand tag-triggered flows.\n\nTags reach a contact from a CSV import, the contact's profile, a bulk action on the\nContacts page, a display's signup tagging, a flow's Tag Contact action, and this API.\nTags synced from Shopify are stored separately, in `shopify_tags`.\n\nTo find contacts by tag, filter `/v1/contacts?tag=`; `/v1/tags` lists every tag in the\naccount.\n","example":["vip","repeat-buyer"],"uniqueKey":"data.tags","typeLabel":"string[]"},"shopify_tags":{"type":"array","items":{"type":"string","uniqueKey":"data.shopify_tags.items.[INDEX]","typeLabel":"string"},"description":"The contact's tags synced from their Shopify customer record, normalized the same way as\n`tags`. Read-only here: they change when the Shopify customer's tags change. Filter\n`/v1/contacts?shopify_tag=` to find contacts by one.\n","example":["wholesale"],"uniqueKey":"data.shopify_tags","typeLabel":"string[]"},"custom_fields":{"type":"object","description":"The contact's custom field values. Values are usually strings, but integration-written fields\ncan carry other JSON scalars (e.g. numeric loyalty point balances).\n","additionalProperties":true,"example":{"loyalty_tier":"gold","referral_code":"JANE2024"},"uniqueKey":"data.custom_fields","typeLabel":"object"},"created_at":{"type":"string","format":"date-time","example":"2025-01-15T10:30:00Z","uniqueKey":"data.created_at","typeLabel":"string\u003cdate-time>"},"updated_at":{"type":"string","format":"date-time","example":"2025-03-20T14:22:00Z","uniqueKey":"data.updated_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"data","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"data":{"id":"cus_a1b2c3d4e5f6g7h8","first_name":"Janet","last_name":"Doe","email":"jane@example.com","email_consent":"unsubscribed","phone_number":"+15551234567","sms_consent":"subscribed","tags":["vip","wholesale"],"custom_fields":{"loyalty_tier":"gold"},"created_at":"2025-01-15T10:30:00Z","updated_at":"2025-04-01T12:15:00Z"}},"examples":{"Example":{"title":"Example","value":{"data":{"id":"cus_a1b2c3d4e5f6g7h8","first_name":"Janet","last_name":"Doe","email":"jane@example.com","email_consent":"unsubscribed","phone_number":"+15551234567","sms_consent":"subscribed","tags":["vip","wholesale"],"custom_fields":{"loyalty_tier":"gold"},"created_at":"2025-01-15T10:30:00Z","updated_at":"2025-04-01T12:15:00Z"}}}},"exampleType":"examples"}},"exampleType":"examples"},"911d0fc5-db27-4d88-a110-2602db31b191":{"description":"The request body is not valid JSON.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"malformed_json","message":"The request body is not valid JSON."}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"malformed_json","message":"The request body is not valid JSON."}}}},"exampleType":"examples"}},"exampleType":"examples"},"f34e0dbc-cf8c-4e80-b515-f4581952435b":{"description":"Missing or invalid bearer token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"unauthorized","message":"Bearer token is missing or invalid"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"unauthorized","message":"Bearer token is missing or invalid"}}}},"exampleType":"examples"}},"exampleType":"examples"},"bc01ec0f-6ebb-43f1-bb13-d68145c1915c":{"description":"`insufficient_scope` when the token lacks the required scope for this endpoint.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"insufficient_scope","message":"Token does not have the required scope"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"insufficient_scope","message":"Token does not have the required scope"}}}},"exampleType":"examples"}},"exampleType":"examples"},"b1c338d3-a9cb-46eb-81ab-2b7bfada67d7":{"description":"The requested resource does not exist or does not belong to your account.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"not_found","message":"Not found"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"not_found","message":"Not found"}}}},"exampleType":"examples"}},"exampleType":"examples"},"0190e31f-de82-4f7e-9bf3-1e6f2afd707a":{"description":"One or more fields failed validation.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"validation_failed","message":"One or more fields are invalid","details":[{"field":"email","message":"is required"}]}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"validation_failed","message":"One or more fields are invalid","details":[{"field":"email","message":"is required"}]}}}},"exampleType":"examples"}},"exampleType":"examples"},"0c557dbf-a0d7-490f-803b-eef56c8aaca5":{"description":"Rate limit exceeded. Retry after the specified time.","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"},"example":42},"X-RateLimit-Limit-Minute":{"description":"Maximum requests allowed per minute.","schema":{"type":"integer"},"example":60},"X-RateLimit-Remaining-Minute":{"description":"Requests remaining in the current minute window.","schema":{"type":"integer"},"example":0},"X-RateLimit-Reset-Minute":{"description":"Unix timestamp when the minute window resets.","schema":{"type":"integer"},"example":1711929600},"X-RateLimit-Limit-Day":{"description":"Maximum requests allowed per day.","schema":{"type":"integer"},"example":10000},"X-RateLimit-Remaining-Day":{"description":"Requests remaining in the current day window.","schema":{"type":"integer"},"example":9500},"X-RateLimit-Reset-Day":{"description":"Unix timestamp when the day window resets.","schema":{"type":"integer"},"example":1712016000}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["invalid_client","invalid_scope","unauthorized","insufficient_scope","forbidden","paid_plan_required","api_access_required","segment_builder_required","not_found","no_connected_store","conflict","contacts_not_ready","validation_failed","idempotency_key_reused","rate_limited","store_unavailable","store_rate_limited","not_a_draft","design_changed","sms_missing","email_missing","ab_test_draft","idempotency_key_reused","template_unavailable","design_unavailable","render_failed"],"example":"validation_failed","isRequired":true,"uniqueKey":"error.code","typeLabel":"enum\u003cstring>"},"message":{"type":"string","example":"One or more fields are invalid","isRequired":true,"uniqueKey":"error.message","typeLabel":"string"},"details":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","example":"email","uniqueKey":"error.details.items.[INDEX].field","typeLabel":"string"},"message":{"type":"string","example":"is required","uniqueKey":"error.details.items.[INDEX].message","typeLabel":"string"}},"uniqueKey":"error.details.items.[INDEX]","typeLabel":"object"},"uniqueKey":"error.details","typeLabel":"object[]"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":{"code":"rate_limited","message":"Rate limit exceeded"}},"examples":{"Example":{"title":"Example","value":{"error":{"code":"rate_limited","message":"Rate limit exceeded"}}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"4b026326-17a4-49ca-8669-46bcd53a85a7":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API token or OAuth access token","description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","scopes":[],"schemeName":"bearerAuth"}}},"servers":{"97f63e03-f020-41b7-a5b9-e312bbfed47d":{"url":"https://api.privy.com/v1","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","bearerFormat":"API token or OAuth access token","description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Send either an API token or an OAuth access token as\n`Authorization: Bearer \u003ctoken>`. See the Authentication page for details.\n","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"}]},"originalFileLocation":"openapi/privy-api.yaml"},"subdomain":"privy","siteName":"Privy Knowledge Base","title":"Update a contact - Privy Knowledge Base","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-05-27T22:21:44.683Z","originalFileLocation":"docs/api-reference/update-contact.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Update an existing contact identified by its unique id. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: first_name, last_name, email, phone_number, tags, custom_fields. email and phone_number can only be set when the existing value is null. Once populated, they cannot be changed or cleared. Consent fields: email_consent, sms_consent. Use these to subscribe, unsubscribe, or otherwise manage a contact\u0026#x27;s marketing consent. When sms_consent is set to subscribed and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass send_welcome_sms: false to suppress this message if you have already collected consent outside of Privy. Required scope: contacts_write\">\u003cmeta data-mint-head name=\"application-name\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Update a contact - Privy Knowledge Base\">\u003cmeta data-mint-head property=\"og:description\" content=\"Update an existing contact identified by its unique id. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: first_name, last_name, email, phone_number, tags, custom_fields. email and phone_number can only be set when the existing value is null. Once populated, they cannot be changed or cleared. Consent fields: email_consent, sms_consent. Use these to subscribe, unsubscribe, or otherwise manage a contact\u0026#x27;s marketing consent. When sms_consent is set to subscribed and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass send_welcome_sms: false to suppress this message if you have already collected consent outside of Privy. Required scope: contacts_write\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://help.privy.com/docs/api-reference/update-contact\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://privy.mintlify.site/_mintlify/api/og/v2?division=Contacts\u0026amp;title=Update+a+contact\u0026amp;description=Update+an+existing+contact+identified+by+its+unique+%60id%60.%0AInclude+one+or+more+fields+to+change.+Field+updates+and+consent+changes%0Acan+be+combined+in+a+single+re\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=230e5942feaad7073dd2f32267585712dc13c29de6efd11794af801905b8c0e1\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Update a contact - Privy Knowledge Base\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Update an existing contact identified by its unique id. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: first_name, last_name, email, phone_number, tags, custom_fields. email and phone_number can only be set when the existing value is null. Once populated, they cannot be changed or cleared. Consent fields: email_consent, sms_consent. Use these to subscribe, unsubscribe, or otherwise manage a contact\u0026#x27;s marketing consent. When sms_consent is set to subscribed and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass send_welcome_sms: false to suppress this message if you have already collected consent outside of Privy. Required scope: contacts_write\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://privy.mintlify.site/_mintlify/api/og/v2?division=Contacts\u0026amp;title=Update+a+contact\u0026amp;description=Update+an+existing+contact+identified+by+its+unique+%60id%60.%0AInclude+one+or+more+fields+to+change.+Field+updates+and+consent+changes%0Acan+be+combined+in+a+single+re\u0026amp;theme=a5dbdd3119e247d04186b21c\u0026amp;signature=230e5942feaad7073dd2f32267585712dc13c29de6efd11794af801905b8c0e1\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/privy/fvbglk3MPcKWjtyG/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Privy Knowledge Base\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#254E5A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://help.privy.com/docs/api-reference/update-contact\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/api-reference/update-contact.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://help.privy.com/#organization\",\"name\":\"Privy Knowledge Base\",\"url\":\"https://help.privy.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/privy/fGrkZt933tBjY_zl/logo/light.svg?fit=max\u0026auto=format\u0026n=fGrkZt933tBjY_zl\u0026q=85\u0026s=36a01db426b7c94fac423778765cd517\"}},{\"@type\":\"WebSite\",\"@id\":\"https://help.privy.com#website\",\"name\":\"Privy Knowledge Base\",\"url\":\"https://help.privy.com\",\"publisher\":{\"@id\":\"https://help.privy.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://help.privy.com/docs/api-reference/update-contact#webpage\",\"url\":\"https://help.privy.com/docs/api-reference/update-contact\",\"name\":\"Update a contact\",\"description\":\"Update an existing contact identified by its unique id. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: first_name, last_name, email, phone_number, tags, custom_fields. email and phone_number can only be set when the existing value is null. Once populated, they cannot be changed or cleared. Consent fields: email_consent, sms_consent. Use these to subscribe, unsubscribe, or otherwise manage a contact's marketing consent. When sms_consent is set to subscribed and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass send_welcome_sms: false to suppress this message if you have already collected consent outside of Privy. Required scope: contacts_write\",\"dateModified\":\"2026-05-27T22:21:44.683Z\",\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"},\"breadcrumb\":{\"@id\":\"https://help.privy.com/docs/api-reference/update-contact#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://help.privy.com/docs/api-reference/update-contact#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Contacts\",\"item\":\"https://help.privy.com/docs/api-reference/list-contacts\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Update a contact\",\"item\":\"https://help.privy.com/docs/api-reference/update-contact\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://help.privy.com/docs/api-reference/update-contact#apireference\",\"headline\":\"Update a contact\",\"name\":\"Update a contact\",\"description\":\"Update an existing contact identified by its unique id. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: first_name, last_name, email, phone_number, tags, custom_fields. email and phone_number can only be set when the existing value is null. Once populated, they cannot be changed or cleared. Consent fields: email_consent, sms_consent. Use these to subscribe, unsubscribe, or otherwise manage a contact's marketing consent. When sms_consent is set to subscribed and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass send_welcome_sms: false to suppress this message if you have already collected consent outside of Privy. Required scope: contacts_write\",\"url\":\"https://help.privy.com/docs/api-reference/update-contact\",\"mainEntityOfPage\":{\"@id\":\"https://help.privy.com/docs/api-reference/update-contact#webpage\"},\"dateModified\":\"2026-05-27T22:21:44.683Z\",\"publisher\":{\"@id\":\"https://help.privy.com/#organization\"},\"isPartOf\":{\"@id\":\"https://help.privy.com#website\"}}]}\u003c/script>","agentPointerHref":"/docs/api-reference/update-contact.md","siteName":"Privy Knowledge Base","nav":{"global":null,"tabs":[{"tab":"Learn","icon":"house","pages":[{"title":"Learn","href":"/docs/learn/home"}]},{"tab":"Developer","icon":"square-terminal","groups":[{"group":"API Reference","pages":[{"title":"API Overview","sidebarTitle":"Overview","icon":"book-open","href":"/docs/api-reference/overview"},{"title":"Authentication","sidebarTitle":"Authentication","icon":"lock","href":"/docs/api-reference/authentication"},{"title":"API Tokens","sidebarTitle":"API Tokens","icon":"key","href":"/docs/api-reference/api-tokens"},{"title":"Rate Limits","sidebarTitle":"Rate Limits","icon":"gauge","href":"/docs/api-reference/rate-limits"},{"title":"Errors","sidebarTitle":"Errors","icon":"triangle-exclamation","href":"/docs/api-reference/errors"},{"title":"API Changelog","sidebarTitle":"Changelog","icon":"clock-rotate-left","href":"/docs/api-reference/changelog"}]},{"group":"Account","pages":[{"title":"Get account","openapi":"openapi/privy-api.yaml GET /account","href":"/docs/api-reference/get-account"},{"title":"Get account setup","openapi":"openapi/privy-api.yaml GET /account/setup","href":"/docs/api-reference/get-account-setup"}]},{"group":"Contacts","pages":[{"title":"List contacts","openapi":"openapi/privy-api.yaml GET /contacts","href":"/docs/api-reference/list-contacts"},{"title":"Get a contact","openapi":"openapi/privy-api.yaml GET /contacts/{id}","href":"/docs/api-reference/get-contact"},{"title":"Create a contact","openapi":"openapi/privy-api.yaml POST /contacts","description":"Create a new contact. At least one of `email` or `phone_number` is required.\n\nIf a contact with the same email or phone number already exists, a `409 Conflict`\nerror is returned with the `id` of the existing contact in `error.id`. Use the **Update a contact** endpoint to modify existing contacts.\n\nIf a previously deleted contact matches the provided email or phone number,\nthe contact is restored with the new data.\n\nWhen `sms_consent` is `subscribed`, Privy automatically sends a TCPA-required\nwelcome SMS to the contact. Pass `send_welcome_sms: false` to suppress this\nmessage if you have already collected consent outside of Privy.\n\n**Required scope:** `contacts_write`\n","href":"/docs/api-reference/create-contact"},{"title":"Update a contact","openapi":"openapi/privy-api.yaml PATCH /contacts/{id}","href":"/docs/api-reference/update-contact"},{"title":"Delete a contact","openapi":"openapi/privy-api.yaml DELETE /contacts/{id}","description":"Soft-delete a contact identified by its unique `id`.\n\nDeleted contacts can be restored if a new contact is created with\nthe same email or phone number via the **Create a contact** endpoint.\n\n**Required scope:** `contacts_write`\n","href":"/docs/api-reference/delete-contact"},{"title":"List a contact's activity","openapi":"openapi/privy-api.yaml GET /contacts/{id}/events","href":"/docs/api-reference/list-contact-activity"}]},{"group":"Imports","pages":[{"title":"List contact imports","openapi":"openapi/privy-api.yaml GET /imports","href":"/docs/api-reference/list-imports"},{"title":"Get a contact import","openapi":"openapi/privy-api.yaml GET /imports/{id}","href":"/docs/api-reference/get-import"}]},{"group":"Tags","pages":[{"title":"List tags","openapi":"openapi/privy-api.yaml GET /tags","href":"/docs/api-reference/list-tags"},{"title":"Get a tag","openapi":"openapi/privy-api.yaml GET /tags/{id}","href":"/docs/api-reference/get-tag"}]},{"group":"Campaigns","pages":[{"title":"List campaigns","openapi":"openapi/privy-api.yaml GET /campaigns","href":"/docs/api-reference/list-campaigns"},{"title":"Get a campaign","openapi":"openapi/privy-api.yaml GET /campaigns/{id}","href":"/docs/api-reference/get-campaign"}]},{"group":"Displays","pages":[{"title":"List displays","openapi":"openapi/privy-api.yaml GET /displays","href":"/docs/api-reference/list-displays"},{"title":"Get a display","openapi":"openapi/privy-api.yaml GET /displays/{id}","href":"/docs/api-reference/get-display"}]},{"group":"Coupons","pages":[{"title":"List coupons","openapi":"openapi/privy-api.yaml GET /coupons","href":"/docs/api-reference/list-coupons"},{"title":"Get a coupon","openapi":"openapi/privy-api.yaml GET /coupons/{id}","href":"/docs/api-reference/get-coupon"},{"title":"Check a coupon code","openapi":"openapi/privy-api.yaml GET /coupons/{id}/codes/{code}","href":"/docs/api-reference/check-coupon-code"}]},{"group":"Reports","pages":[{"title":"Get business report summary","openapi":"openapi/privy-api.yaml GET /reports/summary","href":"/docs/api-reference/get-report-summary"},{"title":"List campaign performance","openapi":"openapi/privy-api.yaml GET /reports/campaigns","href":"/docs/api-reference/list-campaign-performance"},{"title":"Get campaign performance","openapi":"openapi/privy-api.yaml GET /reports/campaigns/{campaign_id}","href":"/docs/api-reference/get-campaign-performance"},{"title":"List flow performance","openapi":"openapi/privy-api.yaml GET /reports/flows","href":"/docs/api-reference/list-flow-performance"},{"title":"Get flow performance","openapi":"openapi/privy-api.yaml GET /reports/flows/{flow_id}","href":"/docs/api-reference/get-flow-performance"},{"title":"List display performance","openapi":"openapi/privy-api.yaml GET /reports/displays","href":"/docs/api-reference/list-display-performance"},{"title":"Get display performance","openapi":"openapi/privy-api.yaml GET /reports/displays/{display_id}","href":"/docs/api-reference/get-display-performance"},{"title":"List top products","openapi":"openapi/privy-api.yaml GET /reports/top_products","href":"/docs/api-reference/list-top-products"}]},{"group":"Flows","pages":[{"title":"List flows","openapi":"openapi/privy-api.yaml GET /flows","href":"/docs/api-reference/list-flows"},{"title":"Get a flow","openapi":"openapi/privy-api.yaml GET /flows/{id}","href":"/docs/api-reference/get-flow"}]},{"group":"Segments","pages":[{"title":"List segments","openapi":"openapi/privy-api.yaml GET /segments","href":"/docs/api-reference/list-segments"},{"title":"Get a segment","openapi":"openapi/privy-api.yaml GET /segments/{id}","href":"/docs/api-reference/get-segment"},{"title":"List a segment's contacts","openapi":"openapi/privy-api.yaml GET /segments/{id}/contacts","href":"/docs/api-reference/list-segment-contacts"}]},{"group":"Orders","pages":[{"title":"Order placed","openapi":"openapi/privy-api.yaml POST /orders/placed","href":"/docs/api-reference/order-placed"},{"title":"List orders","openapi":"openapi/privy-api.yaml GET /orders","href":"/docs/api-reference/list-orders"},{"title":"Get an order","openapi":"openapi/privy-api.yaml GET /orders/{order_id}","href":"/docs/api-reference/get-order"}]},{"group":"Products","pages":[{"title":"List products","openapi":"openapi/privy-api.yaml GET /products","href":"/docs/api-reference/list-products"},{"title":"Get a product","openapi":"openapi/privy-api.yaml GET /products/{id}","href":"/docs/api-reference/get-product"},{"title":"List product collections","openapi":"openapi/privy-api.yaml GET /product_collections","href":"/docs/api-reference/list-product-collections"},{"title":"Get a product collection","openapi":"openapi/privy-api.yaml GET /product_collections/{id}","href":"/docs/api-reference/get-product-collection"},{"title":"List a collection's products","openapi":"openapi/privy-api.yaml GET /product_collections/{id}/products","href":"/docs/api-reference/list-collection-products"},{"title":"List a product's collections","openapi":"openapi/privy-api.yaml GET /products/{id}/collections","href":"/docs/api-reference/list-collections-for-product"}]},{"group":"Events","pages":[{"title":"Ingest an event","openapi":"openapi/privy-api.yaml POST /events","href":"/docs/api-reference/ingest-event"},{"title":"Send cart events from your storefront","sidebarTitle":"Browser events","href":"/docs/api-reference/browser-events"}]}]}]},"basePath":"","title":"Update a contact - Privy Knowledge Base","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C9Wu0MeN.js","utils-jWgu-6Qf.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DBD8f9qn.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BGuX1ui5.js","snippetPresets-Evy63nQB.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BQHO1lnV.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-B6C8m-t_.js","shallow-BG4cT0fH.js","getApiPlaygroundDisplay-CgEPrE-D.js","CodeSnippet-CU8JyZ9N.js","CodeSnippets-BnxHU32T.js","Page-D6S0Yh6q.js","getPastedJson-CwiYOonh.js","icon-DYDpWmDf.js","MethodPill-C-J-l7_c.js","DuplicateIcon-B6ARwg9w.js","createIcon-Dsv4MtDq.js","DynamicMarkdown-CtasenyM.js","SectionHeading-YNcgYwjB.js","axios-vUo_bRtp.js","Markdown-CwLx6PAg.js","clsx-C3kuh_dz.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CmKHfscc.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-U3mI6Ljh.js"]}