Mail

Change flags and labels

Marks messages read, starred or answered, and adds or removes labels. Takes a batch, so one call can change hundreds of messages.

POST /v1/folders/:folder_id/messages/flags

Permission

The key must be granted mail.messages.write

A key without it gets 403 insufficient_scope, with the missing permission named in details.

Takes a batch, so marking five hundred messages read is one call. Reach for set only when you mean "this is the exact set": it removes every flag and label you did not list.

Path parameters

Field Type Description
folder_id required string The folder holding the messages. Flags are set within a folder.

Request body

Field Type Description
message_ids required string[] The messages to change. All must be in the folder above.
op required string add and remove adjust what is there; set replaces it and drops anything not listed. addremoveset
flags string[] System flags to change. readstarredanswereddraftdeleted
labels string[] User-defined labels to change. Any text without a leading backslash.

Request

curl https://api.veruapis.com/v1/folders/:folder_id/messages/flags \
  -X POST \
  -H "Authorization: Bearer vak_live_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "message_ids": ["d9038c5a-3bca-4e27-a016-4b7ad1416948"],
  "op": "add",
  "flags": ["read"],
  "labels": ["Invoices"]
}'

Idempotency-Key is required on every write. Retrying with the same key returns the original response rather than repeating the operation, so a timeout is something you retry rather than something you investigate.

Response

Field Type Description
id string
flags object The flags after the change, not the ones you sent. Its fields are below.
labels string[]

The flags

Field Type Description
read boolean The IMAP Seen flag. Absent means unread.
starred boolean The IMAP Flagged bit. One star, not a colour.
answered boolean Set automatically when you reply through this API.
draft boolean
deleted boolean Marked for removal but still present until the folder is expunged.
{
  "data": [
  {
    "id": "d9038c5a-3bca-4e27-a016-4b7ad1416948",
    "flags": { "read": true, "starred": false, "answered": false, "draft": false, "deleted": false },
    "labels": ["Invoices"]
  }
],
  "meta": { "request_id": "req_01j8z9...", "timestamp": "2026-09-02T10:00:00Z" }
}
Worth knowing

Takes a batch, so marking five hundred messages read is one call rather than five hundred. op is add, remove or set — reach for set only when you mean "this is the exact label set", because it drops every label you did not list.

Errors

Every failure uses the same shape, with a stable string code you can branch on. See the error reference.

Related

POST /v1/folders/:folder_id/messages/flags

folder_id
Sends this body to your own workspace, for real. Edit it before running.