> For the complete documentation index, see [llms.txt](https://flapjax.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://flapjax.gitbook.io/docs/rest-api/reference/people-events/upsert-person-by-external-id.md).

# Upsert Person by External ID

## Upsert person by external ID

> Creates the person if no person with the given \`external\_id\` exists; otherwise updates the existing person. Returns \*\*201\*\* on create and \*\*200\*\* on update.<br>

```json
{"openapi":"3.0.3","info":{"title":"Listener API","version":"1.0.0"},"tags":[{"name":"upsert-person"}],"servers":[{"url":"https://{domain}/v1","variables":{"domain":{"default":"your-domain","description":"Your deployment domain"}}}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token with the required scope for the endpoint. Pass via the `Authorization: Bearer <token>` header.\n"}},"parameters":{"PersonExternalId":{"name":"external_id","in":"path","required":true,"description":"The external identifier assigned to the person.","schema":{"type":"string"}}},"schemas":{"CreatePersonRequest":{"type":"object","description":"Request body for creating a new person. All fields are optional. Consent fields default to `false` if not provided.\n","properties":{"external_id":{"type":"string","description":"External identifier for the person. Must be unique within your organization."},"first_name":{"type":"string","description":"First name."},"last_name":{"type":"string","description":"Last name."},"email":{"type":"string","format":"email","description":"Email address."},"mobile_prefix":{"type":"string","description":"Mobile phone country prefix (e.g. `+1`, `+44`)."},"mobile_number":{"type":"string","description":"Mobile phone number (without country prefix)."},"date_of_birth":{"type":"string","description":"Date of birth."},"language":{"type":"string","description":"Preferred language code."},"email_consent":{"type":"boolean","description":"Email channel consent. Defaults to `false`. This is a summary of the person's consent answers on the email channel: `false` refuses every consent purpose on the channel, `true` grants only the purpose marked as that channel's default and leaves the other purposes on their own defaults.\n","default":false},"sms_consent":{"type":"boolean","description":"SMS channel consent. Defaults to `false`. Behaves like `email_consent` on the SMS channel.\n","default":false},"push_notification_consent":{"type":"boolean","description":"Push notification consent. Defaults to `false`. A plain flag — consent purposes only apply to the `email` and `sms` channels.\n","default":false},"attribute_values":{"type":"object","description":"Custom attribute key-value pairs. Keys must match attribute keys configured on your organization's person attributes. Relationship attributes (Person-type and Stack-type) accept plain values which are automatically normalized to `{\"external_id\": \"...\"}` format.\n","additionalProperties":true}}},"ErrorResponse":{"type":"object","description":"Standard error response envelope.","properties":{"error":{"type":"string","description":"Machine-readable error type. Use this for programmatic error handling.\n","enum":["operation_failed","failed_binding_json","invalid_json","invalid_parameter","not_found","duplicate_entry","rate_limit_exceeded"]},"errorstack":{"type":"object","nullable":true,"description":"Detailed error stack (only present for server errors)."}}}}},"paths":{"/people/upsert/{external_id}":{"put":{"summary":"Upsert person by external ID","operationId":"upsertPersonByExternalId","tags":["upsert-person"],"description":"Creates the person if no person with the given `external_id` exists; otherwise updates the existing person. Returns **201** on create and **200** on update.\n","parameters":[{"$ref":"#/components/parameters/PersonExternalId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePersonRequest"}}}},"responses":{"200":{"description":"Existing person updated."},"201":{"description":"New person created."},"400":{"description":"Invalid request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```
