---
updatedAt: 2026-04-23T13:15:21.000Z
agentTools:
  projectIndex: https://api-docs.omnisend.com/llms.txt
---

# Create or update existing contact

Creates a new contact. If a contact with the provided email identifier already exists, it will be updated instead.
Returns `201 Created` for new contacts and `200 OK` when an existing contact was updated.

**Scopes:**
`contacts.write`

**Rate Limiting:**
This endpoint is rate limited to 400 requests per minute.

# OpenAPI definition

```json
{
  "openapi": "3.0.0",
  "info": {
    "contact": {},
    "description": "Manage contacts.",
    "title": "Contacts API",
    "version": "2026"
  },
  "paths": {
    "/contacts": {
      "post": {
        "description": "Creates a new contact. If a contact with the provided email identifier already exists, it will be updated instead.\nReturns `201 Created` for new contacts and `200 OK` when an existing contact was updated.\n\n**Scopes:**\n`contacts.write`\n\n**Rate Limiting:**\nThis endpoint is rate limited to 400 requests per minute.",
        "parameters": [
          {
            "$ref": "#/components/parameters/APIVersionHeader"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              }
            }
          },
          "description": "Contact to create or update",
          "required": true
        },
        "responses": {
          "200": {
            "description": "Existing contact updated (upsert by email)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "201": {
            "description": "Contact created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            }
          },
          "400": {
            "description": "Request contains invalid or missing fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblem"
                }
              }
            }
          },
          "401": {
            "description": "Authentication is missing or invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "403": {
            "description": "Insufficient permissions for this operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "410": {
            "description": "API version has been retired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitProblem"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error occurred",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        },
        "security": [
          {
            "Bearer": [
              "contacts.write"
            ]
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "summary": "Create or update existing contact",
        "tags": [
          "Contacts"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.omnisend.com/api"
    }
  ],
  "components": {
    "parameters": {
      "APIVersionHeader": {
        "description": "API version that specifies the response format and behaviour",
        "in": "header",
        "name": "Omnisend-Version",
        "required": true,
        "schema": {
          "type": "string",
          "default": "2026-03-15"
        }
      }
    },
    "securitySchemes": {
      "ApiKeyAuth": {
        "description": "API Key authentication. Value format: 'Omnisend-API-Key {api-key}'",
        "in": "header",
        "name": "Authorization",
        "type": "apiKey",
        "x-default": "Omnisend-API-Key your-api-key"
      },
      "Bearer": {
        "type": "oauth2",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://app.omnisend.com/oauth2/token",
            "scopes": {
              "contacts.read": "Read contacts",
              "contacts.write": "Create, update and delete contacts"
            }
          }
        }
      }
    },
    "schemas": {
      "Channel": {
        "description": "Channel subscription status.",
        "properties": {
          "status": {
            "description": "Channel subscription status",
            "enum": [
              "subscribed",
              "unsubscribed",
              "nonSubscribed"
            ],
            "example": "subscribed",
            "type": "string"
          },
          "statusChangedAt": {
            "description": "Timestamp when the channel status last changed",
            "example": "2023-05-22T10:25:14.263Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Consent": {
        "description": "Consent record for a contact channel.",
        "properties": {
          "channel": {
            "description": "Channel type this consent applies to",
            "enum": [
              "email",
              "sms"
            ],
            "example": "email",
            "type": "string"
          },
          "createdAt": {
            "description": "Consent collection timestamp",
            "example": "2021-05-20T12:00:00Z",
            "type": "string"
          },
          "ip": {
            "description": "IP address from which consent was collected",
            "example": "161.1.1.1",
            "type": "string"
          },
          "source": {
            "description": "Source through which consent was obtained (e.g. omnisend-form, api)",
            "example": "api",
            "type": "string"
          },
          "userAgent": {
            "description": "User agent string from the consent collection request",
            "example": "Mozilla/5.0",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactChannelRequest": {
        "description": "Channel subscription details.",
        "properties": {
          "status": {
            "description": "Subscription status",
            "enum": [
              "subscribed",
              "nonSubscribed",
              "unsubscribed"
            ],
            "example": "subscribed",
            "type": "string"
          },
          "statusChangedAt": {
            "description": "Date when the channel status was last changed",
            "example": "2024-01-01T00:00:00Z",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "ContactConsentRequest": {
        "description": "Consent record.",
        "properties": {
          "createdAt": {
            "description": "Consent collection timestamp in RFC3339 format. Defaults to current time if not provided",
            "example": "2026-01-01T00:00:00Z",
            "type": "string"
          },
          "ip": {
            "description": "IP address at time of consent",
            "example": "192.168.1.1",
            "type": "string"
          },
          "source": {
            "description": "Source of consent",
            "example": "omnisend-form",
            "type": "string"
          },
          "userAgent": {
            "description": "User agent at time of consent",
            "example": "Mozilla/5.0",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactIdentifierRequest": {
        "description": "A unique contact identifier (email or phone). For phone: provide the full number with country code prefix in E.164 format (e.g. +1234567890).",
        "properties": {
          "channels": {
            "additionalProperties": {
              "$ref": "#/components/schemas/ContactChannelRequest"
            },
            "description": "Communication channels for this identifier",
            "type": "object"
          },
          "consent": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactConsentRequest"
              }
            ],
            "description": "Consent information"
          },
          "id": {
            "description": "Identifier value. For email: a valid email address. For phone: full phone number in E.164 format with country code prefix (e.g. +1234567890)",
            "example": "example@example.com",
            "type": "string"
          },
          "sendWelcomeMessage": {
            "description": "Whether to send a welcome message for this identifier. Defaults to true. Takes effect only if the welcome workflow is enabled.",
            "example": true,
            "type": "boolean"
          },
          "source": {
            "description": "Source of the identifier",
            "example": "api",
            "type": "string"
          },
          "type": {
            "description": "Identifier type",
            "enum": [
              "email",
              "phone"
            ],
            "example": "email",
            "type": "string"
          }
        },
        "required": [
          "id",
          "type"
        ],
        "type": "object"
      },
      "ContactRequest": {
        "description": "Payload for creating or updating a contact.",
        "properties": {
          "address": {
            "description": "Street, house number, apartment number.",
            "example": "1234 Main St",
            "type": "string"
          },
          "birthdate": {
            "description": "Contact birthdate in YYYY-MM-DD format",
            "example": "1990-01-01",
            "type": "string"
          },
          "city": {
            "description": "City",
            "example": "Los Angeles",
            "type": "string"
          },
          "country": {
            "description": "Country name. Used to derive ISO country code when countryCode is not provided",
            "example": "United States",
            "type": "string"
          },
          "countryCode": {
            "description": "ISO 3166-1 alpha-2 country code. Takes priority over country when both are provided",
            "example": "US",
            "type": "string"
          },
          "createdAt": {
            "description": "Contact creation timestamp. If provided, stored as \"externalCreated\" custom property",
            "example": "2024-01-01T00:00:00Z",
            "type": "string"
          },
          "customProperties": {
            "additionalProperties": true,
            "description": "You can add your own custom properties. Read more in https://api-docs.omnisend.com/reference/contacts#custom-properties",
            "type": "object"
          },
          "firstName": {
            "description": "Contact first name",
            "example": "John",
            "type": "string"
          },
          "gender": {
            "description": "Contact gender. m - male, f - female",
            "enum": [
              "m",
              "f"
            ],
            "example": "m",
            "type": "string"
          },
          "identifiers": {
            "description": "Contact identifiers (email and/or phone)",
            "items": {
              "$ref": "#/components/schemas/ContactIdentifierRequest"
            },
            "type": "array"
          },
          "lastName": {
            "description": "Contact last name",
            "example": "Doe",
            "type": "string"
          },
          "postalCode": {
            "description": "Postal or zip code",
            "example": "90001",
            "type": "string"
          },
          "state": {
            "description": "State or region",
            "example": "New York",
            "type": "string"
          },
          "tags": {
            "description": "Labels assigned to the contact. When creating a contact, it is strongly advised to include a source tag, e.g. \"source: shopify\".",
            "example": [
              "tag1",
              "tag2"
            ],
            "items": {
              "type": "string"
            },
            "maxItems": 100,
            "type": "array"
          },
          "trackingConsents": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactTrackingConsentsRequest"
              }
            ],
            "description": "Contact-level tracking consents"
          }
        },
        "type": "object"
      },
      "ContactResponse": {
        "description": "Contact resource representation.",
        "properties": {
          "address": {
            "description": "Contact Street, house number, apartment number",
            "example": "1234 Main St",
            "type": "string"
          },
          "birthdate": {
            "description": "Contact birthdate in YYYY-MM-DD format",
            "example": "1990-01-01",
            "type": "string"
          },
          "city": {
            "description": "Contact city",
            "example": "Los Angeles",
            "type": "string"
          },
          "consents": {
            "description": "Consent records per channel, sorted by collection date (read-only)",
            "items": {
              "$ref": "#/components/schemas/Consent"
            },
            "readOnly": true,
            "type": "array"
          },
          "country": {
            "description": "Contact country name",
            "example": "United States",
            "type": "string"
          },
          "countryCode": {
            "description": "ISO 3166-1 alpha-2 country code",
            "example": "US",
            "type": "string"
          },
          "createdAt": {
            "description": "Contact creation timestamp (read-only)",
            "example": "2021-05-20T12:00:00Z",
            "readOnly": true,
            "type": "string"
          },
          "customProperties": {
            "additionalProperties": true,
            "description": "Custom contact properties defined for the brand",
            "type": "object"
          },
          "email": {
            "description": "Primary email address derived from the email identifier (read-only)",
            "example": "example@example.com",
            "readOnly": true,
            "type": "string"
          },
          "firstName": {
            "description": "Contact first name",
            "example": "John",
            "type": "string"
          },
          "gender": {
            "description": "Contact gender",
            "enum": [
              "m",
              "f"
            ],
            "example": "m",
            "type": "string"
          },
          "id": {
            "description": "Contact unique identifier (read-only)",
            "example": "60a6170920d91c215e949b5c",
            "readOnly": true,
            "type": "string"
          },
          "identifiers": {
            "description": "Contact identifiers with channel subscription details",
            "items": {
              "$ref": "#/components/schemas/Identifier"
            },
            "type": "array"
          },
          "lastName": {
            "description": "Contact last name",
            "example": "Doe",
            "type": "string"
          },
          "optIns": {
            "description": "Opt-in history per channel, sorted by date (read-only)",
            "items": {
              "$ref": "#/components/schemas/OptIn"
            },
            "readOnly": true,
            "type": "array"
          },
          "phone": {
            "description": "Phone numbers derived from phone identifiers (read-only)",
            "example": [
              "+1234567890"
            ],
            "items": {
              "type": "string"
            },
            "readOnly": true,
            "type": "array"
          },
          "postalCode": {
            "description": "Contact postal or ZIP code",
            "example": "90001",
            "type": "string"
          },
          "segments": {
            "description": "IDs of segments the contact belongs to (read-only)",
            "items": {
              "type": "string"
            },
            "readOnly": true,
            "type": "array"
          },
          "state": {
            "description": "State or province name",
            "example": "New York",
            "type": "string"
          },
          "status": {
            "description": "Email channel subscription status derived from the primary email identifier (read-only)",
            "enum": [
              "subscribed",
              "unsubscribed",
              "nonSubscribed"
            ],
            "example": "subscribed",
            "readOnly": true,
            "type": "string"
          },
          "statuses": {
            "description": "Most recent subscription status per channel, sorted by date (read-only)",
            "items": {
              "$ref": "#/components/schemas/ContactStatus"
            },
            "readOnly": true,
            "type": "array"
          },
          "tags": {
            "description": "Labels assigned to the contact",
            "example": [
              "tag1",
              "tag2",
              "tag3"
            ],
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "trackingConsents": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ContactTrackingConsents"
              }
            ],
            "description": "Contact-level tracking consents (read-only)",
            "readOnly": true
          },
          "updatedAt": {
            "description": "Contact last updated timestamp (read-only)",
            "example": "2021-05-20T12:30:00Z",
            "readOnly": true,
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactStatus": {
        "description": "Contact status per channel.",
        "properties": {
          "channel": {
            "description": "Channel type",
            "enum": [
              "email",
              "sms"
            ],
            "example": "email",
            "type": "string"
          },
          "status": {
            "description": "Channel subscription status",
            "enum": [
              "subscribed",
              "unsubscribed",
              "nonSubscribed"
            ],
            "example": "subscribed",
            "type": "string"
          },
          "statusChangedAt": {
            "description": "Timestamp when the status last changed",
            "example": "2021-05-20T12:00:00Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ContactTrackingConsents": {
        "description": "Contact-level tracking consents.",
        "properties": {
          "emailOpen": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailOpenTrackingConsent"
              }
            ],
            "description": "Email open tracking consent"
          }
        },
        "type": "object"
      },
      "ContactTrackingConsentsRequest": {
        "description": "Contact-level tracking consents.",
        "properties": {
          "emailOpen": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EmailOpenTrackingConsentRequest"
              }
            ],
            "description": "Email open tracking consent"
          }
        },
        "type": "object"
      },
      "EmailOpenTrackingConsent": {
        "description": "Email open tracking consent record.",
        "properties": {
          "status": {
            "description": "Consent status",
            "enum": [
              "given",
              "declined"
            ],
            "example": "given",
            "type": "string"
          },
          "statusDate": {
            "description": "Timestamp when the consent status was collected",
            "example": "2026-08-01T12:00:00Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "EmailOpenTrackingConsentRequest": {
        "description": "Email open tracking consent record.",
        "properties": {
          "status": {
            "description": "Consent status",
            "enum": [
              "given",
              "declined"
            ],
            "example": "given",
            "type": "string"
          },
          "statusDate": {
            "description": "Timestamp when the consent status was collected. Defaults to current time if not provided",
            "example": "2026-08-01T12:00:00Z",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "type": "object"
      },
      "FieldError": {
        "description": "A single field validation failure within a validation error response.",
        "properties": {
          "code": {
            "description": "Error code indicating the type of failure",
            "example": "invalid_format",
            "type": "string"
          },
          "field": {
            "description": "Dot-separated path to the field that failed validation",
            "example": "content.email.subject",
            "type": "string"
          },
          "message": {
            "description": "Human-readable explanation of what is wrong with the field value",
            "example": "Must be a valid email address",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Identifier": {
        "description": "Unique contact identifier (email or phone).",
        "properties": {
          "channels": {
            "additionalProperties": {
              "$ref": "#/components/schemas/Channel"
            },
            "description": "Subscription status per channel, keyed by channel name",
            "type": "object"
          },
          "id": {
            "description": "Identifier value (email address or phone number)",
            "example": "example@example.com",
            "type": "string"
          },
          "type": {
            "description": "Identifier type",
            "enum": [
              "email",
              "phone"
            ],
            "example": "email",
            "type": "string"
          }
        },
        "type": "object"
      },
      "OptIn": {
        "description": "Contact opt-in record.",
        "properties": {
          "channel": {
            "description": "Channel type",
            "enum": [
              "email",
              "sms"
            ],
            "example": "email",
            "type": "string"
          },
          "optInAt": {
            "description": "Timestamp when the opt-in was recorded",
            "example": "2021-05-20T12:00:00Z",
            "type": "string"
          }
        },
        "type": "object"
      },
      "Problem": {
        "description": "Standard error response returned by all API endpoints on failure.",
        "properties": {
          "detail": {
            "description": "Human-readable explanation of this specific error occurrence",
            "example": "A human-readable explanation of the error.",
            "type": "string"
          },
          "instance": {
            "description": "Request trace identifier for support and debugging",
            "example": "urn:omnisend:request:00000000-0000-0000-0000-000000000001",
            "type": "string"
          },
          "status": {
            "description": "HTTP status code",
            "example": 0,
            "type": "integer"
          },
          "title": {
            "description": "Short description of the error type",
            "example": "Problem",
            "type": "string"
          },
          "type": {
            "description": "URI that identifies the error type",
            "example": "https://problems.omnisend.com/problem",
            "type": "string"
          }
        },
        "type": "object"
      },
      "RateLimitProblem": {
        "description": "Error response returned when the rate limit is exceeded. Use the retryAfter value to know when it is safe to retry the request.",
        "properties": {
          "detail": {
            "description": "Human-readable explanation of this specific error occurrence",
            "example": "A human-readable explanation of the error.",
            "type": "string"
          },
          "instance": {
            "description": "Request trace identifier for support and debugging",
            "example": "urn:omnisend:request:00000000-0000-0000-0000-000000000001",
            "type": "string"
          },
          "retryAfter": {
            "description": "Seconds to wait before retrying the request",
            "example": 60,
            "type": "integer"
          },
          "status": {
            "description": "HTTP status code",
            "example": 0,
            "type": "integer"
          },
          "title": {
            "description": "Short description of the error type",
            "example": "Problem",
            "type": "string"
          },
          "type": {
            "description": "URI that identifies the error type",
            "example": "https://problems.omnisend.com/problem",
            "type": "string"
          }
        },
        "type": "object"
      },
      "ValidationProblem": {
        "description": "Error response returned when the request contains invalid input. The errors array lists every field that failed validation.",
        "properties": {
          "detail": {
            "description": "Human-readable explanation of this specific error occurrence",
            "example": "A human-readable explanation of the error.",
            "type": "string"
          },
          "errors": {
            "description": "List of fields that failed validation",
            "items": {
              "$ref": "#/components/schemas/FieldError"
            },
            "type": "array"
          },
          "instance": {
            "description": "Request trace identifier for support and debugging",
            "example": "urn:omnisend:request:00000000-0000-0000-0000-000000000001",
            "type": "string"
          },
          "status": {
            "description": "HTTP status code",
            "example": 0,
            "type": "integer"
          },
          "title": {
            "description": "Short description of the error type",
            "example": "Problem",
            "type": "string"
          },
          "type": {
            "description": "URI that identifies the error type",
            "example": "https://problems.omnisend.com/problem",
            "type": "string"
          }
        },
        "type": "object"
      }
    }
  }
}
```