Skip to content

Update a channel

PATCH
/api/channels/{channelId}

Update channel settings. Only the fields you include in the request body are changed. The config object is merged into the stored configuration: keys you leave out keep their value, and a key sent as null is removed. Keys the platform maintains for a connected mailbox are ignored when sent. A connected mailbox (inbound_mode inbox_api) keeps its from_address, inbound_address, mail_provider and inbound_mode; to move the channel to another mailbox, disconnect it in the dashboard, update the channel, then connect the new mailbox. Setting enabled to true on a connected mailbox first renews its subscription at the mail provider. An email channel’s inbound_mode changes only to subdomain, forwarding or inbox_api; another new mode answers 422. A subdomain channel’s from_address and inbound_address are on a subdomain of a registrable domain: an update that gives it an address on a registrable domain itself, such as support@example.com or support@example.co.uk, answers 422 with the message on that address. A save that keeps the channel’s address is not checked again.

channelId
required
string format: uuid

The unique identifier of the channel to update.

object
welcomeGreetingAttested

EU AI Act Article 50 confirmation for a greeting override in config.welcome_greeting on a voice channel: the same rule as attested on a workspace greeting (voiceGreetings). A new or changed override is refused with 422 and code greeting_attestation_required unless this is true, and refused with code greeting_must_mention_ai when the wording does not mention the assistant. An override without a valid confirmation is replaced at call time by the standard opening line.

boolean
Example
true
displayName

Updated human-readable name.

string
>= 1 characters
config

The configuration keys to change, in the shape for the channel’s type: the email, chat or voice channel config. On an email, chat or voice channel the object is merged into the stored configuration key by key: a key sent replaces its stored value whole, a key left out keeps its value, and a key sent as null is removed. The merged configuration is then validated against the shape for the channel’s type.

object
Any of:
Email channel config

The configuration of an email channel. inbound_mode decides how mail reaches oHallo and which fields the channel needs. A config without inbound_mode is read as subdomain, with inbound_address taken from from_address. While it provisions the channel, oHallo adds keys of its own, marked read-only: the inbound_address it generates, the DNS records to publish, and error_message when provisioning fails. A channel is created in subdomain, forwarding, inbox_api or mail_routing_rule; another inbound_mode on create, or a new mode on update other than subdomain, forwarding or inbox_api, answers 422.

object
One of:
subdomain

A subdomain given to oHallo, for example help.example.com, receives the mail itself. Publish the records in dns_records on it. The channel turns active once the domain is verified. The addresses are on a subdomain of a registrable domain, as the Public Suffix List draws it: an address on a registrable domain itself, such as support@example.com or support@example.co.uk, answers 422 with the message on that address, since an MX record there would receive all of the domain’s mail.

object
inbound_mode

subdomain, which is also how a config without inbound_mode is read.

string
Allowed values: subdomain
from_address
required

The address customers write to and replies come from: an address on the subdomain.

string format: email
Example
support@help.example.com
inbound_address

The address mail is received at, the same as from_address. Required when inbound_mode is sent; without inbound_mode it is taken from from_address.

string format: email
Example
support@help.example.com
domain

The domain the DNS records belong to, written by oHallo.

string
Example
help.example.com
dns_records

The DNS records an email channel needs, written by oHallo. Publish each at the DNS host of its domain. The verification record, the DKIM records and the MX record route and verify mail; SPF and DMARC serve the delivery of replies.

object
verification_txt

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
dkim_cnames
Array<object>

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
mx

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
spf

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
dmarc

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
domain

On a mail_routing_rule channel, the domain the DKIM records belong to.

string
error_message

Why provisioning failed, when the channel’s status is error and the reason is known.

string
Example
{
"allowed_origins": [
"https://www.example.com"
],
"theme": {
"mode": "floating",
"position": "bottom-left"
}
}
enabled

Whether the channel is active.

boolean
workspaceId

Moves the channel to another workspace of the account, and with it under that workspace’s brand. The caller must be allowed to change both workspaces. A voice channel stays in the workspace its phone number is registered to, and a move answers 422.

string format: uuid
phoneNumberId

On a voice channel, the phone number it answers. A voice channel keeps its number: the number it already has is accepted, and any other answers 409. Another channel type answers 400.

string format: uuid

The channel was updated.

A channel represents a communication pathway through which oHallo sends and receives messages. Each channel has a type, configuration, and provisioning status.

object
id
required

Unique identifier for the channel.

string format: uuid
Example
d4e5f6a7-b8c9-0123-4567-890abcdef012
workspaceId
required

Workspace the channel belongs to.

string format: uuid
Example
a1b2c3d4-e5f6-7890-abcd-ef1234567890
tenantId
required

The account the channel belongs to.

string format: uuid
Example
a0b1c2d3-4567-89ab-cdef-0123456789ab
brandId

On a read by id: the brand the channel answers for, which is the brand of its workspace.

string | null format: uuid
channelType
required

Channel type: email, chat, whatsapp or voice_phone. The type decides the shape of config.

string
Example
email
displayName
required

Human-readable name.

string
Example
Support Email
status
required

Where the channel stands. draft: set up but not live; an inbox_api email channel stays in draft until its mailbox is connected in the dashboard. pending_dns: a subdomain, subdomain_with_redirect or mail_routing_rule email channel waits for its DNS records to be published and to resolve; a mail_routing_rule channel waits here until its DKIM records are verified, for up to 72 hours, after which it moves to error. pending_verification: the channel’s DNS records resolve, and oHallo is completing the verification of its domain. pending_setup: a mail_routing_rule or subdomain_with_redirect email channel waits for the first message its mail-flow rule redirects, and turns active when it arrives. pending_inbound: a forwarding email channel waits for the first forwarded message, and turns active when it arrives. pending_activation: a voice channel waits while its phone number is in review with the carrier, and turns active when the number is approved. active: the channel receives and sends messages; a successful connectivity test also sets it, on every channel but a mail_routing_rule one. error: provisioning failed, a connectivity test failed on an active channel, or a connected mailbox needs to be connected again; after a provisioning failure config.error_message says why when the reason is known. The retry endpoint provisions an email channel again, and a connected mailbox is connected again in the dashboard. inactive: a connected mailbox was disconnected, and the channel receives and sends nothing until the mailbox is connected again. deprovisioned: the channel was deleted; channel lists leave it out, and a read by id returns it.

string
Allowed values: draft pending_dns pending_verification pending_setup pending_inbound pending_activation active error inactive deprovisioned
Example
active
enabled
required

Whether the channel is enabled.

boolean
Example
true
provisioningWorkflowId

The id of the run that provisions an email channel; null on a channel no provisioning run was started for, such as a chat, voice or inbox_api channel.

string | null
lastVerifiedAt

When a connectivity test, or the disconnection of a mailbox, last set the channel’s status; null before either.

string | null format: date-time
config
required

The channel’s configuration, in the shape for its channelType: the email channel config for email, the chat channel config for chat and the voice channel config for voice_phone. It holds settings only; channel credentials are stored apart and never returned.

object
Any of:
Email channel config

The configuration of an email channel. inbound_mode decides how mail reaches oHallo and which fields the channel needs. A config without inbound_mode is read as subdomain, with inbound_address taken from from_address. While it provisions the channel, oHallo adds keys of its own, marked read-only: the inbound_address it generates, the DNS records to publish, and error_message when provisioning fails. A channel is created in subdomain, forwarding, inbox_api or mail_routing_rule; another inbound_mode on create, or a new mode on update other than subdomain, forwarding or inbox_api, answers 422.

object
One of:
subdomain

A subdomain given to oHallo, for example help.example.com, receives the mail itself. Publish the records in dns_records on it. The channel turns active once the domain is verified. The addresses are on a subdomain of a registrable domain, as the Public Suffix List draws it: an address on a registrable domain itself, such as support@example.com or support@example.co.uk, answers 422 with the message on that address, since an MX record there would receive all of the domain’s mail.

object
inbound_mode

subdomain, which is also how a config without inbound_mode is read.

string
Allowed values: subdomain
from_address
required

The address customers write to and replies come from: an address on the subdomain.

string format: email
Example
support@help.example.com
inbound_address

The address mail is received at, the same as from_address. Required when inbound_mode is sent; without inbound_mode it is taken from from_address.

string format: email
Example
support@help.example.com
domain

The domain the DNS records belong to, written by oHallo.

string
Example
help.example.com
dns_records

The DNS records an email channel needs, written by oHallo. Publish each at the DNS host of its domain. The verification record, the DKIM records and the MX record route and verify mail; SPF and DMARC serve the delivery of replies.

object
verification_txt

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
dkim_cnames
Array<object>

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
mx

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
spf

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
dmarc

One DNS record to publish.

object
type
required

The record type.

string
Allowed values: TXT CNAME MX
name
required

The record’s name.

string
value
required

The record’s value.

string
priority

The priority of an MX record.

integer
domain

On a mail_routing_rule channel, the domain the DKIM records belong to.

string
error_message

Why provisioning failed, when the channel’s status is error and the reason is known.

string
Example
{
"inbound_mode": "subdomain",
"from_address": "support@help.example.com",
"inbound_address": "support@help.example.com",
"domain": "help.example.com"
}
publicKey

A chat channel’s public key: the data-key of the code that puts the chat on a website. null on the other channel types.

string | null
phoneNumberId

The phone number a voice channel answers; null on the other channel types.

string | null format: uuid
credentialsRef

The reference oHallo uses to read the channel’s stored credentials at runtime, never the credentials themselves; null when none are stored.

string | null
languageOverride

Has no effect.

array | null
publishedVersionId

The channel’s current configuration version.

string | null format: uuid
createdAt
required

Timestamp when the channel was created.

string format: date-time
Example
2026-01-10T08:00:00.000Z
updatedAt
required

Timestamp when the channel was last updated.

string format: date-time
Example
2026-01-10T08:00:00.000Z
welcomeGreetingAttestation

EU AI Act Article 50 confirmation covering the exact greeting override in config.welcome_greeting on a voice channel, composed by the server when the override is saved with welcomeGreetingAttested.

object
attestedByUserId
string
attestedAt
string format: date-time
greetingHash
string
language

The language the override was confirmed in. The confirmation covers the override only while the line’s language (config.language, else the workspace’s operating language) is this language.

string
Example
da
welcomeGreetingAttestationValid

Whether the stored confirmation still covers the override in config.welcome_greeting, in the line’s language. False means callers hear the standard opening line on this number until the override is confirmed again.

boolean

The caller may not change this channel. People need the owner or admin role. An API key needs the channels:write scope; a channel in a workspace outside the key’s brand or workspace restriction answers 404, and so does a move to such a workspace.

Standard error response returned by all endpoints on failure.

object
error
required

A human-readable error message describing what went wrong.

string
Example
Conversation not found
code

A machine-readable reason on some refusals, for example ‘key_lock’ when an API key’s brand or workspace restriction does not cover the action.

string
Example
key_lock
missing_scopes

On a 403 for an API key without a scope the endpoint requires: the scopes the key lacks.

Array<string>
Example
[
"mcp:write"
]
entryId

On a 409 with code duplicate_question or duplicate_rule_text: the knowledge base entry or policy that already holds the question or rule text.

string format: uuid
Example
11223344-5566-4788-99aa-bbccddeeff00
connectionId

On a 422 about one MCP connection a request names, from an assignment or an agent create or update (a connection that does not exist, one listed twice, or one that does not declare a tool named): the connection, as the request named it.

string
undeclaredTools

On the same 422: the tool names the connection does not declare.

Array<string>
Example
[
"get_orders"
]
declaredTools

On the same 422: the tools the connection declares.

Array<string>
Example
[
"get_order",
"search_orders"
]

No channel exists with the given ID in the authenticated tenant.

Standard error response returned by all endpoints on failure.

object
error
required

A human-readable error message describing what went wrong.

string
Example
Conversation not found
code

A machine-readable reason on some refusals, for example ‘key_lock’ when an API key’s brand or workspace restriction does not cover the action.

string
Example
key_lock
missing_scopes

On a 403 for an API key without a scope the endpoint requires: the scopes the key lacks.

Array<string>
Example
[
"mcp:write"
]
entryId

On a 409 with code duplicate_question or duplicate_rule_text: the knowledge base entry or policy that already holds the question or rule text.

string format: uuid
Example
11223344-5566-4788-99aa-bbccddeeff00
connectionId

On a 422 about one MCP connection a request names, from an assignment or an agent create or update (a connection that does not exist, one listed twice, or one that does not declare a tool named): the connection, as the request named it.

string
undeclaredTools

On the same 422: the tool names the connection does not declare.

Array<string>
Example
[
"get_orders"
]
declaredTools

On the same 422: the tools the connection declares.

Array<string>
Example
[
"get_order",
"search_orders"
]

The update changes the from_address, inbound_address, mail_provider or inbound_mode of a connected mailbox (error mailbox_connected, with fields naming them). A phoneNumberId other than the one a voice channel answers also answers 409.

Standard error response returned by all endpoints on failure.

object
error
required

A human-readable error message describing what went wrong.

string
Example
Conversation not found
code

A machine-readable reason on some refusals, for example ‘key_lock’ when an API key’s brand or workspace restriction does not cover the action.

string
Example
key_lock
missing_scopes

On a 403 for an API key without a scope the endpoint requires: the scopes the key lacks.

Array<string>
Example
[
"mcp:write"
]
entryId

On a 409 with code duplicate_question or duplicate_rule_text: the knowledge base entry or policy that already holds the question or rule text.

string format: uuid
Example
11223344-5566-4788-99aa-bbccddeeff00
connectionId

On a 422 about one MCP connection a request names, from an assignment or an agent create or update (a connection that does not exist, one listed twice, or one that does not declare a tool named): the connection, as the request named it.

string
undeclaredTools

On the same 422: the tool names the connection does not declare.

Array<string>
Example
[
"get_orders"
]
declaredTools

On the same 422: the tools the connection declares.

Array<string>
Example
[
"get_order",
"search_orders"
]

Validation error. A field is invalid, or the merged config does not match the shape for the channel’s type; nothing was written. An email channel’s new inbound_mode is not subdomain, forwarding or inbox_api, or a subdomain channel’s new from_address or inbound_address is on a registrable domain itself, such as support@example.com or support@example.co.uk: the message is under details.fieldErrors, on the field it concerns. A voice channel’s greeting and move refusals are described under welcomeGreetingAttested and workspaceId.

Standard error response returned by all endpoints on failure.

object
error
required

A human-readable error message describing what went wrong.

string
Example
Conversation not found
code

A machine-readable reason on some refusals, for example ‘key_lock’ when an API key’s brand or workspace restriction does not cover the action.

string
Example
key_lock
missing_scopes

On a 403 for an API key without a scope the endpoint requires: the scopes the key lacks.

Array<string>
Example
[
"mcp:write"
]
entryId

On a 409 with code duplicate_question or duplicate_rule_text: the knowledge base entry or policy that already holds the question or rule text.

string format: uuid
Example
11223344-5566-4788-99aa-bbccddeeff00
connectionId

On a 422 about one MCP connection a request names, from an assignment or an agent create or update (a connection that does not exist, one listed twice, or one that does not declare a tool named): the connection, as the request named it.

string
undeclaredTools

On the same 422: the tool names the connection does not declare.

Array<string>
Example
[
"get_orders"
]
declaredTools

On the same 422: the tools the connection declares.

Array<string>
Example
[
"get_order",
"search_orders"
]

Turning a connected mailbox back on needs a new subscription at the mail provider, and it failed this time (error mailbox_reenable_failed). The channel stays off; send the request again, or reconnect the mailbox.

Standard error response returned by all endpoints on failure.

object
error
required

A human-readable error message describing what went wrong.

string
Example
Conversation not found
code

A machine-readable reason on some refusals, for example ‘key_lock’ when an API key’s brand or workspace restriction does not cover the action.

string
Example
key_lock
missing_scopes

On a 403 for an API key without a scope the endpoint requires: the scopes the key lacks.

Array<string>
Example
[
"mcp:write"
]
entryId

On a 409 with code duplicate_question or duplicate_rule_text: the knowledge base entry or policy that already holds the question or rule text.

string format: uuid
Example
11223344-5566-4788-99aa-bbccddeeff00
connectionId

On a 422 about one MCP connection a request names, from an assignment or an agent create or update (a connection that does not exist, one listed twice, or one that does not declare a tool named): the connection, as the request named it.

string
undeclaredTools

On the same 422: the tool names the connection does not declare.

Array<string>
Example
[
"get_orders"
]
declaredTools

On the same 422: the tools the connection declares.

Array<string>
Example
[
"get_order",
"search_orders"
]