Skip to content
AgentMail
AgentMail
Extras

Labels and system labels

Labels classify messages and threads, but they also expose service state and control visibility. Use caller-managed labels for your workflow, leave service-owned labels to AgentMail, and treat an absent restricted resource as a permissions question before treating it as missing data.

Use caller-managed labels for application classification

Caller-managed labels are lowercase string tags you apply to messages and threads, such as needs-review, customer-123, or processed. A resource can hold at most 256 labels. The message_update permission is required to change message labels and is also required to change thread labels.

Label mechanismCan the caller change this label?
Caller-managed label, such as needs-reviewYes, by adding or removing it through a label-update request.
Service-owned system label, such as received or deliveredNo. AgentMail maintains it.

Use add_labels and remove_labels to make a targeted change. This Python example adds a workflow label and removes an earlier workflow label from one message:

from agentmail import AgentMail

client = AgentMail()

updated = client.inboxes.messages.update(
    inbox_id="support@example.com",
    message_id="<message-id@example.com>",
    add_labels=["needs-review"],
    remove_labels=["triaged"],
)

print(updated.labels)

The same change is available over PATCH /v0/inboxes/{inbox_id}/messages/{message_id} with add_labels and remove_labels in the JSON body. The response contains the message’s message_id and its resulting labels. Keep the labels in your own namespace so that they describe application state rather than transport or delivery state.

Recognize system labels as service-owned state

A caller cannot add or remove system labels through label creation or update input. Their presence is information to read, not a value to set.

A system label can coexist with caller-managed labels on the same resource. For example, a received message might carry both received and needs-review. Updating the workflow label must leave the system label unchanged.

Do not submit protected system labels

The following protected system labels are rejected when submitted in labels, add_labels, or remove_labels, with a 400 naming the label.

Protected labelWhy the request is rejected
receivedAgentMail assigns inbound receipt state.
sentAgentMail assigns outbound send state.
bouncedAgentMail maintains this delivery-state label.
complainedAgentMail maintains this delivery-state label.
delayedAgentMail maintains this delivery-state label.
deliveredAgentMail maintains this delivery-state label.
rejectedAgentMail maintains this delivery-state label.
openedAgentMail records the first open on a tracked message.
scheduledAgentMail mirrors a draft’s scheduled send state (send_at).

This page does not cover the deliverability conditions behind labels such as bounced or complained. Use the deliverability concepts documentation for those conditions.

Request permission before reading restricted labels

The restricted labels spam, blocked, unauthenticated, and trash are visibility controls. The matching permission for each is a boolean API-key field, set when the key is created or updated.

Restricted labelRequired read permission
spamlabel_spam_read
blockedlabel_blocked_read
unauthenticatedlabel_unauthenticated_read
trashlabel_trash_read

List requests exclude these labels by default. To include one, pass its matching query option, such as include_spam=true, and use a credential with the matching read permission. Both conditions are required.

A direct lookup without the required label-read permission also reports the resource as not found. That response intentionally does not distinguish a hidden resource from an incorrect identifier. Check the credential’s scope, the relevant label permission, and the list request’s include option before assuming data was deleted.

Use inbox events to audit label changes

List inbox events with GET /v0/inboxes/{inbox_id}/events; results are reverse chronological by default. Each event identifies the event_type (label.added or label.removed), message_id, changed label, event_at, and event_id.

Use this trail to establish which message changed, whether a label was added or removed, and when the change occurred. Paginate through the event list when reconstructing a longer history.

Was this page helpful?Suggest editsRaise issue