API Reference

Contacts

Add contact

Adds a contact to the channel account. Provide at least one of phone_number or username. whatsapp_options is WhatsApp-only; unsupported channels return 501 unsupported_by_provider.

POSThttps://api.unifyport.ai/v1/accounts/{account_id}/contacts/add

Supported channels

WhatsApp

Before you call

Use a server-side X-Api-Key for the workspace that owns the resource. Replace every placeholder before running a sample.

Prepare your parameters
account_id
Use data.id from account creation or an account query. Account identifiers belong to the workspace selected by X-Api-Key. Get account

Request parameters

Headers

X-Api-Key
stringrequired

Workspace API key. The workspace is resolved from this header.

Content-Type
stringrequired

Use application/json when sending a JSON request body.

Path parameters

account_id
stringrequired

Identifier used in the contacts route.

Request body

phone_number
string

Phone number containing a country or region code, using digits only with no plus sign, spaces, or separators. Provide phone_number or username.

minLength: 1

username
string

Channel username. Provide username or phone_number; format rules depend on the target channel.

minLength: 1

whatsapp_options
object

Optional WhatsApp-only contact settings. Pass first_name, full_name, and sync_to_device_contacts only as fields nested inside whatsapp_options; omit this object for other channels.

first_name
string

Optional WhatsApp contact first name.

full_name
string

Optional WhatsApp contact full name.

sync_to_device_contacts
boolean

Whether to also save the contact to the system address book of the device linked to this WhatsApp account. Defaults to false.

Understand the result

Read the documented response fields and HTTP status, then follow the related operations for your next step.

Response 200 OK

{
  "request_id": "<REQUEST_ID>",
  "data": {
    "id": "8600000000000@s.whatsapp.net",
    "conversation_id": "123456789012345@lid",
    "display_name": "Alice Example",
    "avatar_url": "",
    "provider_user_id": "8600000000000@s.whatsapp.net",
    "extra": {
      "phone": "8600000000000"
    }
  }
}

Response body

id
string

Contact identifier.

conversation_id
string

Conversation identifier for this contact; use it to send messages or locate the chat.

display_name
string

Contact display name, or an empty string when missing.

avatar_url
string

Contact avatar URL, or an empty string when missing.

provider_user_id
string

Channel-side user identifier for the contact.

is_blocked
boolean

Whether the contact is blocked by the connected account.

extra
object

Provider-specific extra fields, such as phone.

phone
string

Phone number extracted from the WhatsApp phone JID.

first_name
string

Contact short name or given name saved in the current account’s address book.

full_name
string

Full contact name saved in the current account’s address book.

push_name
string

Profile name set by the contact in WhatsApp.

username
string

WhatsApp contact username (provider=whatsapp), independent of the profile name push_name. Lists and details return it only when a non-empty username has been obtained. Absence means currently unknown, not that the contact has not set one; do not clear a saved username based on its absence.

minLength: 1

business_name
string

Business or verified name of the WhatsApp Business account.

redacted_phone
string

Masked phone number when the provider returns only part of the number.

Responses

200

200 OK

Request succeeded. See the example response body.

400

Bad Request

The request body, path, or parameters are invalid.

401

Unauthorized

The X-Api-Key header is missing or invalid.

403

Forbidden

The request is authenticated but is not allowed.

404

Not Found

The requested resource was not found. Check error.code and the current operation.

409

Conflict

The requested operation conflicts with an existing provider account or resource.

500

Internal Server Error

The service encountered an unexpected error.

501

Not Implemented

The selected provider does not implement this operation.

502

Bad Gateway

The provider adapter or upstream provider could not complete the operation.

If the request fails

Inspect HTTP status and error.code/numeric_code, and keep request_id for diagnosis. Correct invalid parameters, complete required authorization or check runtime state as appropriate. Confirm the outcome before retrying a send or another write. Error reference

Read HTTP status, error.code and error.numeric_code together in the context of the current operation. Numeric codes are strings. Keep request_id for diagnosis; it is not an idempotency key or a task identifier.

invalid_request · 10000 · 400

Check the JSON body and required fields.

What to do: Correct the parameters for this operation and channel before requesting again. Repeating an unchanged invalid request will not resolve the error.

Illustrative JSON; message varies with the actual cause · 400 · 10000
{
  "request_id": "req_example",
  "error": {
    "code": "invalid_request",
    "numeric_code": "10000",
    "message": "Invalid request parameters"
  }
}
invalid_target_workspace · 11003 · 400

The workspace override target is empty or malformed. Remove the override header and use the API key belonging to the intended workspace.

When it occurs: Applies when the request includes the X-Workspace-Id workspace override header.

What to do: Correct the parameters for this operation and channel before requesting again. Repeating an unchanged invalid request will not resolve the error.

Illustrative JSON; message varies with the actual cause · 400 · 11003
{
  "request_id": "req_example",
  "error": {
    "code": "invalid_target_workspace",
    "numeric_code": "11003",
    "message": "Invalid target workspace"
  }
}
provider_invalid_request · 30001 · 400

Check the channel-specific fields and formats.

What to do: Correct the parameters for this operation and channel before requesting again. Repeating an unchanged invalid request will not resolve the error.

Illustrative JSON; message varies with the actual cause · 400 · 30001
{
  "request_id": "req_example",
  "error": {
    "code": "provider_invalid_request",
    "numeric_code": "30001",
    "message": "Provider rejected the request"
  }
}
invalid_api_key · 11001 · 401

Check whether the API key is correct and enabled.

What to do: Keep request_id and the structured codes, and investigate the current operation before taking another action.

Illustrative JSON; message varies with the actual cause · 401 · 11001
{
  "request_id": "req_example",
  "error": {
    "code": "invalid_api_key",
    "numeric_code": "11001",
    "message": "Invalid API key"
  }
}
missing_api_key · 11000 · 401

Add the X-Api-Key header.

What to do: Keep request_id and the structured codes, and investigate the current operation before taking another action.

Example · 401 · 11000
{
  "request_id": "req_xxx",
  "error": {
    "code": "missing_api_key",
    "numeric_code": "11000",
    "message": "Missing X-Api-Key header"
  }
}
workspace_override_forbidden · 11002 · 403

The request attempts a workspace override that this API key is not allowed to use. Remove the override header and use the API key belonging to the intended workspace.

When it occurs: Applies when the request includes the X-Workspace-Id workspace override header.

What to do: Keep request_id and the structured codes, and investigate the current operation before taking another action.

Illustrative JSON; message varies with the actual cause · 403 · 11002
{
  "request_id": "req_example",
  "error": {
    "code": "workspace_override_forbidden",
    "numeric_code": "11002",
    "message": "Workspace override is not allowed"
  }
}
target_workspace_not_found · 11004 · 404

The overridden workspace was not found or is unavailable. Verify workspace ownership, remove the override header and use the intended workspace’s API key; repeated requests do not grant access.

When it occurs: Applies when the request includes the X-Workspace-Id workspace override header.

What to do: Check the target identifier, resource ownership and current workspace. Do not treat a confirmed missing or inaccessible target as a temporary service failure to retry automatically.

Illustrative JSON; message varies with the actual cause · 404 · 11004
{
  "request_id": "req_example",
  "error": {
    "code": "target_workspace_not_found",
    "numeric_code": "11004",
    "message": "Target workspace not found"
  }
}
account_binding_not_found · 30006 · 409

The account has no active channel connection binding; check its status.

What to do: Query authorization and runtime status, then choose refresh, start or reconnect only when appropriate for the intended state and channel. A connection problem alone does not prove logout. Confirm running before dependent business operations.

Illustrative JSON; message varies with the actual cause · 409 · 30006
{
  "request_id": "req_example",
  "error": {
    "code": "account_binding_not_found",
    "numeric_code": "30006",
    "message": "Account is not bound to an available server"
  }
}
egress_configuration_pending · 20032 · 409

The platform default network configuration cannot currently be confirmed or loaded. This does not mean the account is logged out.

When it occurs: The operation uses platform-managed network capacity or a fixed default network configuration.

What to do: Keep request_id and check the account or creation result before another write. Wait for capacity or configuration recovery, or contact support. Do not repeatedly create accounts, change networks, or restart accounts automatically.

Illustrative JSON; message varies with the actual cause · 409 · 20032
{
  "request_id": "req_example",
  "error": {
    "code": "egress_configuration_pending",
    "numeric_code": "20032",
    "message": "Account network configuration is pending verification"
  }
}
provider_not_ready · 30009 · 409

The connection is not ready. Check authorization and runtime_status before retrying.

What to do: Query authorization and runtime status, then choose refresh, start or reconnect only when appropriate for the intended state and channel. A connection problem alone does not prove logout. Confirm running before dependent business operations.

Illustrative JSON; message varies with the actual cause · 409 · 30009
{
  "request_id": "req_example",
  "error": {
    "code": "provider_not_ready",
    "numeric_code": "30009",
    "message": "Provider client is not ready"
  }
}
provider_not_ready · 30014 · 409

The provider instance needed by this account is missing. This is a runtime availability problem, not proof that authorization expired.

What to do: Query authorization and runtime status, then choose refresh, start or reconnect only when appropriate for the intended state and channel. A connection problem alone does not prove logout. Confirm running before dependent business operations.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 409 · 30014
{
  "request_id": "req_example",
  "error": {
    "code": "provider_not_ready",
    "numeric_code": "30014",
    "message": "Provider instance is missing"
  }
}
provider_not_ready · 30015 · 409

The provider runtime is stopped. Confirm whether that is intentional before starting it; a stopped runtime does not itself mean logout.

What to do: Query authorization and runtime status, then choose refresh, start or reconnect only when appropriate for the intended state and channel. A connection problem alone does not prove logout. Confirm running before dependent business operations.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 409 · 30015
{
  "request_id": "req_example",
  "error": {
    "code": "provider_not_ready",
    "numeric_code": "30015",
    "message": "Provider runtime is stopped"
  }
}
create_contact_failed · 20020 · 500

Check account_id and use an X-Api-Key for the workspace that owns the account. An account not found in this workspace cannot be accessed with this key.

When it occurs: Applies when the account is not found; the existing HTTP status and operation code are preserved, while numeric_code identifies the missing account.

What to do: Check the target identifier, resource ownership and current workspace. Do not treat a confirmed missing or inaccessible target as a temporary service failure to retry automatically.

Illustrative JSON; message varies with the actual cause · 500 · 20020
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "20020",
    "message": "Account not found"
  }
}
create_contact_failed · 30010 · 500

The provider could not complete the operation. message can include the original cause after “Provider operation failed:”; the reason text varies and is not a stable program interface.

When it occurs: Applies when the channel supplies no more specific failure classification; the current operation’s error is preserved.

What to do: List or query existing resources to check whether creation already took effect before creating another. Correct the underlying cause and keep request_id; do not create duplicates automatically.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 500 · 30010
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "30010",
    "message": "Provider operation failed"
  }
}
create_contact_failed · 30017 · 500

The upstream channel explicitly rejected excessive request frequency. This numeric classification preserves the operation’s existing HTTP status and code.

What to do: Pause requests and retry later within a bounded policy. No fixed delay or Retry-After handling is guaranteed here. Confirm the previous result before retrying a write.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 500 · 30017
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "30017",
    "message": "Provider rate limit exceeded"
  }
}
create_contact_failed · 30018 · 500

The account’s provider App State baseline is out of sync. This is an account synchronization condition, not a generic request-format error.

What to do: Wait for the provider to restore the account’s App State baseline, then check current state before retrying. Do not infer that credentials are invalid or begin reauthorization solely from this classification.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 500 · 30018
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "30018",
    "message": "Provider app state is out of sync"
  }
}
create_contact_failed · 30021 · 500

The account was not connected to the messaging platform for this request. WhatsApp contact creation can return 500 / create_contact_failed / 30021. This does not prove logout or that the current runtime status is still disconnected; query the current status before choosing a recovery action.

What to do: Pause operations that require the connection. First call POST /v1/accounts/{account_id}/runtime/refresh, recover according to the latest state and confirm runtime_status=running before business requests. Confirm the previous write result before resending.

Channels: WhatsApp

Illustrative JSON; message varies with the actual cause · 500 · 30021
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "30021",
    "message": "Account is not connected to the messaging platform"
  }
}
create_contact_failed · 35003 · 500

Add contact: resource creation failed or could not be confirmed.

What to do: List or query existing resources to check whether creation already took effect before creating another. Correct the underlying cause and keep request_id; do not create duplicates automatically.

Illustrative JSON; message varies with the actual cause · 500 · 35003
{
  "request_id": "req_example",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "35003",
    "message": "Failed to create contact"
  }
}
create_contact_failed · 35009 · 500

WhatsApp did not recognize the target number as an active contact in this lookup. This does not prove it is unregistered or permanently unavailable.

What to do: Check the country code, phone number and WhatsApp registration with the user, and inspect error.message. Retry only after checking the cause; do not repeatedly submit the same number automatically.

Channels: WhatsApp

Example · 500 · 35009
{
  "request_id": "req_example_contact_not_active",
  "error": {
    "code": "create_contact_failed",
    "numeric_code": "35009",
    "message": "Target phone number was not recognized as an active WhatsApp contact"
  }
}
unsupported_by_provider · 30003 · 501

The channel does not support this operation; choose a supported operation.

What to do: Use a channel and action listed as supported. Repeating the same request does not add capabilities or grant beta access.

Example · 501 · 30003
{
  "request_id": "req_xxx",
  "error": {
    "code": "unsupported_by_provider",
    "numeric_code": "30003",
    "message": "Operation not supported by this provider"
  }
}
provider_adapter_not_found · 30004 · 502

The channel service is unavailable. Check status or try again later; confirm the result before retrying writes.

What to do: List or query existing resources to check whether creation already took effect before creating another. Correct the underlying cause and keep request_id; do not create duplicates automatically.

Illustrative JSON; message varies with the actual cause · 502 · 30004
{
  "request_id": "req_example",
  "error": {
    "code": "provider_adapter_not_found",
    "numeric_code": "30004",
    "message": "Provider adapter unavailable"
  }
}
provider_unavailable · 30002 · 502

The channel service is unavailable. Check status or try again later; confirm the result before retrying writes.

What to do: List or query existing resources to check whether creation already took effect before creating another. Correct the underlying cause and keep request_id; do not create duplicates automatically.

Example · 502 · 30002
{
  "request_id": "req_example_provider_unavailable",
  "error": {
    "code": "provider_unavailable",
    "numeric_code": "30002",
    "message": "Provider service unavailable"
  }
}
provider_unavailable · 30010 · 502

The provider could not complete the operation. message can include the original cause after “Provider operation failed:”; the reason text varies and is not a stable program interface.

What to do: List or query existing resources to check whether creation already took effect before creating another. Correct the underlying cause and keep request_id; do not create duplicates automatically.

Channels: WhatsApp

Example · 502 · 30010
{
  "request_id": "req_example_operation_failed",
  "error": {
    "code": "provider_unavailable",
    "numeric_code": "30010",
    "message": "Provider operation failed: Example operation could not be completed"
  }
}
provider_unavailable · 30021 · 502

The account was not connected to the messaging platform for this request. WhatsApp contact creation can return 500 / create_contact_failed / 30021. This does not prove logout or that the current runtime status is still disconnected; query the current status before choosing a recovery action.

What to do: Pause operations that require the connection. First call POST /v1/accounts/{account_id}/runtime/refresh, recover according to the latest state and confirm runtime_status=running before business requests. Confirm the previous write result before resending.

Channels: WhatsApp

Example · 502 · 30021
{
  "request_id": "req_example_connection_disconnected",
  "error": {
    "code": "provider_unavailable",
    "numeric_code": "30021",
    "message": "example operation: websocket not connected"
  }
}