Skip to content
List Objects
  1. Docs
  2. Reference
  3. Objects

Objects

The workspace's objects: definitions, records, queries and relationships.

List Objects#

GET/v1/objects
API keyobjects_list

Every Object type in the workspace, each with its fields. Two kinds:

  • custom — record systems the workspace made (Deals, Candidates, Properties…). Their records are read and written under /v1/objects/{key}/records.
  • system — Attria's built-in Objects (keys agents, websites, image_boards, video_boards, files). They can be related to, and carry extra custom fields, but their records belong to their own feature.

A field's key is what record values use; type says what a value may be; options lists the choices of a select, multi_select or stage field (write either the option's id or its label).

Query parameters

  • kindstringoptional

    Only this kind.

    "custom""system"
  • limitintegeroptional

    How many items to return, 1–100. Default 25.

    Default 25min 1max 100
  • cursorstringoptional

    The next_cursor from the previous page. Omit for the first page.

Can fail with 400 · 401 · 404 · 429 · 500 — the shape is in Errors & limits.

GET
curl "https://app.attria.io/api/v1/objects" \
  -H "Authorization: Bearer $ATTRIA_API_KEY"

Create an Object#

POST/v1/objects
API keyobjects_create

Make a new record system — the same thing the Objects screen's New object makes, with a Table view. The Object's key is the plural name in snake_case (Sales leads → sales_leads); if that key is taken the answer is 409 naming the existing Object, so a retried create never makes a twin.

Each field needs a label and a type (text, long_text, number, currency, date (YYYY-MM-DD), datetime (ISO 8601), boolean, email, phone, url, select, multi_select, stage, image, file). Choice types need options. title_field names the field that titles a record (default: the first).

JSON
{
  "singular_name": "Deal",
  "plural_name": "Deals",
  "fields": [
    { "label": "Name", "type": "text", "required": true },
    { "label": "Value", "type": "currency" },
    { "label": "Stage", "type": "stage", "options": ["New", "Proposal", "Won", "Lost"] },
    { "label": "Contact email", "type": "email" }
  ]
}

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Bodyapplication/json

  • singular_namestringrequired

    One record: Deal.

    max length 80
  • plural_namestringrequired

    Many: Deals. Also makes the key.

    max length 80
  • descriptionstringoptional
    Default ""max length 2000
  • iconstringoptional

    A Lucide icon name, e.g. Briefcase.

    Default "Box"max length 64
  • colorstringoptional
    Default "#64748b"max length 32
  • title_fieldstringoptional

    Key of the field that titles a record. Default: the first field.

  • fieldsarray of objectrequired
  • fields[].labelstringrequired

    What people see: Deal value.

    max length 120
  • fields[].keystringoptional

    Stable key used in record values. Default: the label in snake_case (deal_value).

  • fields[].typestringoptional

    The field's type.

    "text""long_text""number""currency""date""datetime""boolean""email""phone""url""select""multi_select""stage""image""file"Default "text"
  • fields[].optionsarray of string | objectoptional

    For select, multi_select and stage: the choices, as labels or { id, label, color }.

  • fields[].requiredbooleanoptional

    Records must have a value.

    Default false

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

POST
curl -X POST "https://app.attria.io/api/v1/objects" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "singular_name": "Deal",
    "plural_name": "Deals",
    "fields": [
      {
        "label": "Name",
        "type": "text",
        "required": true
      },
      {
        "label": "Value",
        "type": "currency"
      },
      {
        "label": "Stage",
        "type": "stage",
        "options": [
          "New",
          "Proposal",
          "Won",
          "Lost"
        ]
      },
      {
        "label": "Contact email",
        "type": "email"
      }
    ]
  }'

Get an Object#

GET/v1/objects/{object}
API keyobjects_get

One Object type and its fields, by key (deals) or id. Read this before writing records: it says which values keys exist, their types, which are required, and the options a choice field accepts.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

Can fail with 400 · 401 · 404 · 429 · 500 — the shape is in Errors & limits.

GET
curl "https://app.attria.io/api/v1/objects/deals" \
  -H "Authorization: Bearer $ATTRIA_API_KEY"

Change an Object#

PATCH/v1/objects/{object}
API keyobjects_update

Rename an Object, or add, change and remove its fields. Only what you send changes.

  • fields — each item whose key already exists updates that field (label, type, options, required); a new key (or a label with no key) adds a field.
  • remove_fields — keys of custom fields to delete. Their values stay on existing records but are no longer shown or validated.

Built-in fields (origin: system) cannot be changed. The Object's key never changes, so code that uses it keeps working.

JSON
{
  "fields": [
    { "key": "stage", "label": "Stage", "type": "stage", "options": ["New", "Proposal", "Negotiation", "Won", "Lost"] },
    { "label": "Close date", "type": "date" }
  ],
  "remove_fields": ["legacy_notes"]
}

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Bodyapplication/json

  • singular_namestringoptional
    max length 80
  • plural_namestringoptional
    max length 80
  • descriptionstringoptional
    max length 2000
  • iconstringoptional
    max length 64
  • colorstringoptional
    max length 32
  • title_fieldstringoptional
  • fieldsarray of objectoptional

    Fields to change (by existing key) or add.

  • fields[].keystringoptional

    An existing field's key to change it; a new key (or none, with a label) to add one.

  • fields[].labelstringoptional
    max length 120
  • fields[].typestringoptional
    "text""long_text""number""currency""date""datetime""boolean""email""phone""url""select""multi_select""stage""image""file"
  • fields[].optionsarray of string | objectoptional

    Replaces the field's choices.

  • fields[].requiredbooleanoptional
  • remove_fieldsarray of stringoptional

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

PATCH
curl -X PATCH "https://app.attria.io/api/v1/objects/deals" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "fields": [
      {
        "key": "stage",
        "label": "Stage",
        "type": "stage",
        "options": [
          "New",
          "Proposal",
          "Negotiation",
          "Won",
          "Lost"
        ]
      },
      {
        "label": "Close date",
        "type": "date"
      }
    ],
    "remove_fields": [
      "legacy_notes"
    ]
  }'

List and query records#

GET/v1/objects/{object}/records
API keyobjects_records_list

An Object's records, newest change first. Narrow with:

  • filter — a JSON object of field key → value; every pair must match exactly. Values are normalised as on write (a choice matches by option id or label; "true" matches a boolean). For a multi_select a list matches records that contain all of it. null matches an empty field.
  • search — text found anywhere in the record's values (case-insensitive).
  • sort — updated_at, created_at or any field key; prefix - for descending. Default -updated_at.

Page with limit and the next_cursor of the previous page.

Request
GET /v1/objects/deals/records?filter={"stage":"Won"}&sort=-value&limit=20

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

Query parameters

  • filterstringoptional

    JSON object: {"stage":"Won","owner_email":"ana@acme.com"} (URL-encode it).

  • searchstringoptional

    Text to find in any value.

  • sortstringoptional

    updated_at, created_at or a field key; - prefix for descending.

    Default "-updated_at"
  • limitintegeroptional

    How many items to return, 1–100. Default 25.

    Default 25min 1max 100
  • cursorstringoptional

    The next_cursor from the previous page. Omit for the first page.

Can fail with 400 · 401 · 404 · 429 · 500 — the shape is in Errors & limits.

GET
curl "https://app.attria.io/api/v1/objects/deals/records?filter=%7B%22stage%22%3A%22Won%22%7D&sort=-value&limit=20" \
  -H "Authorization: Bearer $ATTRIA_API_KEY"

Create a record#

POST/v1/objects/{object}/records
API keyobjects_records_create

Add one record. values is keyed by field key and checked against the Object's fields exactly as the app checks them: unknown keys, missing required fields and values of the wrong type are refused with 422 and a message naming the field. Choice fields accept an option's id or label and store the id.

Send an Idempotency-Key: a retry with the same key returns the record the first request made instead of a duplicate.

JSON
{ "values": { "name": "Acme renewal", "value": 12000, "stage": "Proposal", "contact_email": "ana@acme.com" } }

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Bodyapplication/json

  • valuesobjectrequired

    Field key → value.

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

POST
curl -X POST "https://app.attria.io/api/v1/objects/deals/records" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "values": {
      "name": "Acme renewal",
      "value": 12000,
      "stage": "Proposal",
      "contact_email": "ana@acme.com"
    }
  }'

Get a record#

GET/v1/objects/{object}/records/{id}
API keyobjects_records_get

One record of an Object, with all its values.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

  • idstringrequired

Can fail with 400 · 401 · 404 · 429 · 500 — the shape is in Errors & limits.

GET
curl "https://app.attria.io/api/v1/objects/deals/records/5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a" \
  -H "Authorization: Bearer $ATTRIA_API_KEY"

Update a record#

PATCH/v1/objects/{object}/records/{id}
API keyobjects_records_update

Change some of a record's values. Only the keys you send change; every other value is kept. The change is merged in the database under a row lock, so it never overwrites an edit an Agent or a person made a moment earlier. Send null to clear a field. Values are validated like a create (422 names the field).

JSON
{ "values": { "stage": "Won", "value": 14500 } }

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

  • idstringrequired

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Bodyapplication/json

  • valuesobjectrequired

    Field key → new value.

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

PATCH
curl -X PATCH "https://app.attria.io/api/v1/objects/deals/records/5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "values": {
      "stage": "Won",
      "value": 14500
    }
  }'

Delete a record#

DELETE/v1/objects/{object}/records/{id}
API keyobjects_records_delete

Delete one record, and every relationship that points to or from it. This cannot be undone.

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

  • idstringrequired

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

del
curl -X DELETE "https://app.attria.io/api/v1/objects/deals/records/5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

List a record's relationships#

GET/v1/objects/{object}/records/{id}/relationships
API keyobjects_relationships_list

Everything this record is linked to, in both directions. Each relationship has a relation_key (account, owner, mentioned_in…), a direction (outgoing when this record is the source) and the other end: its Object key and its id.

Works for any Object, built-in ones too: /v1/objects/agents/records/{agent_id}/relationships lists what an Agent is linked to.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

  • idstringrequired

Query parameters

  • relation_keystringoptional

    Only this kind of link.

Can fail with 400 · 401 · 404 · 429 · 500 — the shape is in Errors & limits.

GET
curl "https://app.attria.io/api/v1/objects/deals/records/5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a/relationships" \
  -H "Authorization: Bearer $ATTRIA_API_KEY"

Link a record to another#

POST/v1/objects/{object}/records/{id}/relationships
API keyobjects_relationships_create

Link this record (the source) to another record of any Object (the target) under a relation_key — company, owner, related_to… — in snake_case. Both ends must be in this workspace. The target can be a built-in Object: { "object": "agents", "id": "<agent id>" }.

The same source, target and relation_key is one link: sending it again returns the existing one.

JSON
{ "relation_key": "company", "target": { "object": "companies", "id": "0b6f…" }, "label": "Buyer" }

Send an Idempotency-Key header: a retry with the same key replays the first result instead of doing the work twice.

Path parameters

  • objectstringrequired

    The Object's key (deals) or id.

  • idstringrequired

Headers

  • Idempotency-Keystringoptional

    Any unique string (a UUID) per logical write. Retrying with the same key replays the original result.

Bodyapplication/json

  • relation_keystringrequired

    What the link means, snake_case: company.

  • targetobjectrequired
  • target.objectstringrequired

    The Object's key (deals) or id.

  • target.idstring · uuidrequired

    The target record's id.

  • labelstringoptional
    Default ""max length 200
  • metadataobjectoptional
    Default {}

Can fail with 400 · 401 · 402 · 404 · 409 · 429 · 500 — the shape is in Errors & limits.

POST
curl -X POST "https://app.attria.io/api/v1/objects/deals/records/5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a/relationships" \
  -H "Authorization: Bearer $ATTRIA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "relation_key": "company",
    "target": {
      "object": "companies",
      "id": "5b7e2c8e-1f0a-4c3d-9e8b-7a6f5d4c3b2a"
    },
    "label": "Buyer"
  }'