eusend-dev Contact properties API

The custom fields contacts carry, and the fallbacks they render with.

Operations 5

POST /contact-properties Declare a contact property #
GET /contact-properties List contact properties #
GET /contact-properties/{id} Get a contact property #
PATCH /contact-properties/{id} Update a contact property #
DELETE /contact-properties/{id} Delete a contact property #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/eusend-dev:eusend-dev-contact-properties-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

eusend-dev-contact-properties-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: eusend Contact properties API
  version: 1.0.0
  summary: EU-native transactional and marketing email API.
  description: 'eusend sends transactional and marketing email from infrastructure that stays inside the European Union — processing, storage and delivery alike.


    **When to use this API.** Reach for eusend to send application email from server-side code: password resets, receipts, verification codes, notifications, and opt-in marketing broadcasts to a list you own. It is a good fit when GDPR or EU data residency is a requirement, when you are migrating off Resend, SendGrid, Mailgun, Postmark or SES, or when you need SMTP relay rather than an HTTP call. It is not a fit for inbox hosting, for reading a user’s mailbox, or for sending to purchased or scraped lists.


    **Getting started.** Create an account, verify a sending domain by publishing the DNS records the domain endpoints hand back, then `POST /emails`. A key prefixed `eu_test_` exercises the whole pipeline without delivering anything.


    **Authentication.** Every authenticated endpoint takes `Authorization: Bearer `. Keys are `eu_live_…` or `eu_test_…`, and carry either `full_access` or the send-only `sending_access` permission.


    **Errors.** Non-2xx responses are always `{ "error": string, "code": string }`. Branch on `code`; the list is enumerated on the `Error` schema.


    **Conventions.** Request bodies use snake_case and reject unknown properties. Response bodies use camelCase, except the pagination cursor and a handful of endpoints noted inline. List endpoints are cursor-paginated, newest first. Every response carries `X-Request-Id`.'
  termsOfService: https://eusend.dev/legal/terms
  contact:
    name: eusend support
    email: support@eusend.dev
    url: https://eusend.dev/support
  license:
    name: Proprietary
    url: https://eusend.dev/legal/terms
servers:
- url: https://api.eusend.dev
  description: Production
security:
- bearerAuth: []
tags:
- name: Contact properties
  description: The custom fields contacts carry, and the fallbacks they render with.
paths:
  /contact-properties:
    post:
      operationId: createContactProperty
      summary: Declare a contact property
      description: Declaring a property is optional — one that arrives on a contact write without ever being declared registers itself as a `string`. Declaring it is what gives it a type and a fallback value. The key and type are fixed at creation.
      tags:
      - Contact properties
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateContactPropertyRequest'
      responses:
        '201':
          description: Created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactProperty'
        '400':
          description: The request body or query failed validation (`VALIDATION_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, malformed, or revoked API key (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: A property with that name already exists (`CONFLICT`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded (`RATE_LIMITED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    get:
      operationId: listContactProperties
      summary: List contact properties
      description: Every property the organization has defined, by name. Unpaginated — the registry is capped at 100 entries.
      tags:
      - Contact properties
      responses:
        '200':
          description: The properties.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListContactPropertiesResponse'
        '401':
          description: Missing, malformed, or revoked API key (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded (`RATE_LIMITED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  /contact-properties/{id}:
    get:
      operationId: getContactProperty
      summary: Get a contact property
      description: One property definition by id.
      tags:
      - Contact properties
      parameters:
      - name: id
        in: path
        required: true
        description: The contact property id.
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The property.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactProperty'
        '401':
          description: Missing, malformed, or revoked API key (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such resource on this organization (`NOT_FOUND`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded (`RATE_LIMITED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    patch:
      operationId: updateContactProperty
      summary: Update a contact property
      description: Only the fallback value can change. Renaming or retyping a property would have to rewrite every contact and every broadcast body spelling `{{old_key}}`, so both are a delete and a create.
      tags:
      - Contact properties
      parameters:
      - name: id
        in: path
        required: true
        description: The contact property id.
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateContactPropertyRequest'
      responses:
        '200':
          description: Updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactProperty'
        '400':
          description: The request body or query failed validation (`VALIDATION_ERROR`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing, malformed, or revoked API key (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such resource on this organization (`NOT_FOUND`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded (`RATE_LIMITED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    delete:
      operationId: deleteContactProperty
      summary: Delete a contact property
      description: Deletes the definition **and** strips the key from every contact in the organization. Not undoable. Leaving the values behind would keep the property rendering in broadcasts, and the next contact write carrying that key would register it again.
      tags:
      - Contact properties
      parameters:
      - name: id
        in: path
        required: true
        description: The contact property id.
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Deleted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteContactPropertyResponse'
        '401':
          description: Missing, malformed, or revoked API key (`UNAUTHORIZED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: No such resource on this organization (`NOT_FOUND`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: Rate limit exceeded (`RATE_LIMITED`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ListContactPropertiesResponse:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ContactProperty'
    Error:
      type: object
      description: Every non-2xx response from the API has this shape. `code` is stable and safe to branch on; `error` is a human sentence that may change.
      required:
      - error
      - code
      properties:
        error:
          type: string
          description: Human-readable explanation of the failure.
        code:
          type: string
          enum:
          - UNAUTHORIZED
          - FORBIDDEN
          - NOT_FOUND
          - VALIDATION_ERROR
          - RATE_LIMITED
          - MONTHLY_LIMIT_EXCEEDED
          - DAILY_LIMIT_EXCEEDED
          - PLAN_LIMIT_EXCEEDED
          - ALL_SUPPRESSED
          - RECIPIENT_DOMAIN_UNDELIVERABLE
          - DOMAIN_NOT_VERIFIED
          - SENDING_SUSPENDED
          - ACCOUNT_RESTRICTED
          - WORKSPACE_INACTIVE
          - SENDER_NOT_PERMITTED
          - SERVICE_PAUSED
          - LIST_SEND_HELD
          - BROADCAST_HELD
          - ATTACHMENT_STORAGE_ERROR
          - INTERNAL_ERROR
          - CONFLICT
          - BAD_REQUEST
          - PAYLOAD_TOO_LARGE
          description: Stable machine-readable error code.
        request_id:
          type: string
          description: Correlation id, returned on 500s and echoed in the `X-Request-Id` header on every response. Quote it in support requests.
    DeleteContactPropertyResponse:
      type: object
      required:
      - deleted
      - contactsUpdated
      properties:
        deleted:
          type: boolean
        contactsUpdated:
          type: integer
          description: How many contacts had the key stripped from them.
    UpdateContactPropertyRequest:
      type: object
      required:
      - fallback_value
      additionalProperties: false
      properties:
        fallback_value:
          type:
          - string
          - 'null'
          maxLength: 500
          description: The only mutable field. Send `null` to clear the fallback.
    CreateContactPropertyRequest:
      type: object
      required:
      - key
      additionalProperties: false
      properties:
        key:
          type: string
          maxLength: 40
          description: Lowercase letters, digits and underscores, starting with a letter. `email`, `name`, `first_name`, `last_name` and `full_name` are built in and are rejected here. Cannot be changed after creation.
        type:
          type: string
          enum:
          - string
          - number
          default: string
          description: Checked when a contact is written. Values are carried and rendered as strings either way — `number` is a validation rule, not a formatting instruction. Cannot be changed after creation.
        fallback_value:
          type:
          - string
          - 'null'
          maxLength: 500
    ContactProperty:
      type: object
      required:
      - id
      - key
      - type
      - fallbackValue
      - createdAt
      properties:
        id:
          type: string
          format: uuid
        key:
          type: string
        type:
          type: string
          enum:
          - string
          - number
        fallbackValue:
          type:
          - string
          - 'null'
          description: Substituted into `{{key}}` for contacts carrying no value of their own. `null` renders empty.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type:
          - string
          - 'null'
          format: date-time
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An eusend API key, sent as `Authorization: Bearer eu_live_…`. Create one in the dashboard under API keys.'
externalDocs:
  description: eusend documentation
  url: https://eusend.dev/docs