Edit an attribute definition

Search Documentation

Search across all developer documentation

attributes

Edit an attribute definition

PUT /v1/attributes/{id}
Auth required api.attributes.manage

Edits an attribute's name, type, enum values, and description. The registry is authoritative: the edit always applies — it is never blocked. Each edit is classified by its impact on dependent Segments and the class is returned as mutation_class:

  • free — no effect on any predicate (description change, enum widen, or moving between string and enum, which compile to the same cast).
  • safe_but_stale — an enum value was removed; predicates stay valid but may compare against a value that can no longer be written.
  • disruptive — a rename or a cast-class change (e.g. string→number). Segments that reference the attribute keep evaluating best-effort but carry a standing eval_warning until their predicate is re-saved. For a disruptive edit the response includes an impact block (affected segments
    • projected org-wide drop-out). Preview the impact first via /v1/attributes/{id}/preview.

Path parameters

id string required

The attribute's UUID or, when the value does not parse as a UUID, its org-unique name — the same name PUT /v1/attributes/by-name/{name} is keyed on and a Segment predicate compiles against. Unknown handles read as 404 not_found.

Request body

Content type: application/json

name string required

Lowercase identifier (letters, digits, underscore), referenced in SendQL as attr.<name>.

type string enum optional

Required for an ordinary attribute; ignored when formula is set (the derived type is inferred).

One of: string, number, bool, datetime, enum

enum_values array<string> optional

Required when type is enum; must be empty/omitted otherwise.

description string optional
formula string optional

Creates a derived attribute (SND-1067) whose value SendOps computes and maintains from the contact's event/activity stream. One aggregate over one source: exists, count, first, or last of a SES event name (send, open, click, …) or activity.<name> — e.g. exists(send), count(activity.order). The value type is inferred; type/enum_values are ignored. Derived attributes are managed-only (not promotable) and their formula is immutable (change = delete + recreate). Create-only.

Responses

Errors follow the RFC 7807 problem format — see the error reference.

200 The updated definition with the mutation class and (for a disruptive edit) the impact application/json
attribute object required

Fields of attribute:

id string<uuid> required
name string required

Lowercase identifier; referenced in SendQL as attr.<name>.

type string enum required

One of: string, number, bool, datetime, enum

enum_values array<string> optional

Allowed values when type is enum; omitted otherwise.

description string required
formula string optional

For a derived attribute (SND-1067): the aggregate expression SendOps computes over the contact's event/activity stream, e.g. exists(send), count(activity.order), last(open). Present only for derived attributes; their value is maintained by SendOps (read-only) and type is inferred (exists→bool, count→number, first/last→datetime).

created_at string<date-time> required
updated_at string<date-time> required
mutation_class string enum required

How an edit affects dependent Segment predicates: free (no effect), safe_but_stale (an enum value was removed; predicates stay valid), or disruptive (a rename or cast-class change that raises a standing per-segment warning).

One of: free, safe_but_stale, disruptive

impact object optional

Present only for a disruptive edit; the committed impact.

401 Missing, malformed, or unknown API key application/problem+json
403 Key lacks the required scope or plan limit violated application/problem+json
404 Resource not found application/problem+json
409 The mutation is rejected by a state rule rather than a bad request. The code is conflict. application/problem+json
422 A query parameter, path value or body field failed validation. The body is a validation_failed Problem. When the refusal is about a reference — a segment key, template slug, topic or attribute name the organization does not have — it additionally carries validation_code, field, line/column, missing, candidates and next_step, so a client can correct the call without a second round of guessing. See ValidationProblem. application/problem+json
429 Per-org rate limit exceeded application/problem+json
500 Unexpected server-side failure. The code is internal_error. The request_id field can be quoted to SendOps support to investigate. application/problem+json