CRM

Custom objects

Your own kinds of records — shops, machines, contracts… — with their properties, linked to contacts, companies, deals and each other.

A kind of object (type) has a key (used in paths, e.g. shops), a name, its properties and what its records can link to (links: contact, company, deal, record). Records have a name, values (by property key) and an owner. Creating, changing or deleting kinds needs the owner or an admin of the workspace.

In a chat
Copy a ready promptPaste it in any AI: it reads the docs and follows the rules of the API.
Open in Claude or ChatGPTA new conversation with the prompt already written.
This page as MarkdownFor an AI that cannot open links: paste the text itself.
In your editor
Claude Code or CodexAdd this line to CLAUDE.md or AGENTS.md.Meetzy API reference (read before calling the API): https://www.meetzy.ai/llms-full.txt
CursorSettings › Indexing & Docs › Add Doc, then type @Meetzy in the chat.https://www.meetzy.ai/llms-full.txt
Connect Meetzy as tools (MCP)The AI can then read and change your CRM itself — Claude Code:claude mcp add --transport http meetzy https://app.meetzy.ai/api/mcp/mcp
Same for Codexcodex mcp add meetzy --url https://app.meetzy.ai/api/mcp/mcp
GET/objects/types

List the kinds of objects

Every kind with its properties and how many records it has (count).

Scope: read
Request
curl "https://app.meetzy.ai/api/v1/objects/types" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/types", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://app.meetzy.ai/api/v1/objects/types",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "types": [
    {
      "id": "…",
      "key": "shops",
      "name": "Shop",
      "plural": "Shops",
      "icon": "store",
      "color": "#FF9500",
      "properties": [
        {
          "key": "city",
          "label": "City",
          "type": "text",
          "list": true
        },
        {
          "key": "format",
          "label": "Format",
          "type": "select",
          "options": [
            "Flagship",
            "Corner"
          ]
        }
      ],
      "links": [
        "contact",
        "company",
        "deal"
      ],
      "count": 12
    }
  ],
  "setup_needed": false
}
POST/objects/types

Create a kind of object

Each property: { key?, label, type, options?, required?, list? } — type is text, textarea, number, currency, date, select, multiselect, boolean, url, email, phone or user (a teammate’s email); options for selects; list: true shows it in lists. Keys come from labels.

Scope: write

Body

namestringrequired
Singular (Shop).
pluralstring
Plural (default: name + s).
keystring
Key in paths (default from the plural).
iconstring
box, store, wrench, contract, event, truck, building, car, package, ticket, course, property, project, star, place, device, product, care.
colorstring
Hex color.
descriptionstring
What it is.
propertiesobject[]
Its properties.
linksstring[]
What its records link to (default contact, company, deal).
Request
curl -X POST "https://app.meetzy.ai/api/v1/objects/types" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Shop",
    "plural": "Shops",
    "icon": "store",
    "properties": [
      {
        "label": "City",
        "type": "text",
        "list": true
      },
      {
        "label": "Size (m²)",
        "type": "number"
      }
    ]
  }'
const res = await fetch("https://app.meetzy.ai/api/v1/objects/types", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "name": "Shop",
    "plural": "Shops",
    "icon": "store",
    "properties": [
      {
        "label": "City",
        "type": "text",
        "list": true
      },
      {
        "label": "Size (m²)",
        "type": "number"
      }
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://app.meetzy.ai/api/v1/objects/types",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "name": "Shop",
        "plural": "Shops",
        "icon": "store",
        "properties": [
            {
                "label": "City",
                "type": "text",
                "list": True
            },
            {
                "label": "Size (m²)",
                "type": "number"
            }
        ]
    },
)
data = res.json()
Response201

Empty answer.

PATCH/objects/types/{type}

Update a kind of object

By id or key. properties replaces the list. Each property: { key?, label, type, options?, required?, list? } — type is text, textarea, number, currency, date, select, multiselect, boolean, url, email, phone or user (a teammate’s email); options for selects; list: true shows it in lists. Keys come from labels.

Scope: write

Path parameters

typestringrequired
Path parameter.

Body

namestring
Singular.
pluralstring
Plural.
iconstring
Icon.
colorstring
Color.
descriptionstring
Description.
propertiesobject[]
Properties (full list).
linksstring[]
What its records link to.
positioninteger
Order in the sidebar.
Request
curl -X PATCH "https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "links": [
      "company",
      "deal"
    ]
  }'
const res = await fetch("https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D", {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "links": [
      "company",
      "deal"
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.patch(
    "https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "links": ["company", "deal"]
    },
)
data = res.json()
Response200

Empty answer.

DELETE/objects/types/{type}

Delete a kind of object

Refused (409) while it has records, unless force=1 — which deletes them with their links.

Scope: delete

Path parameters

typestringrequired
Path parameter.

Query parameters

forcestring
1 deletes its records too.
Request
curl -X DELETE "https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://app.meetzy.ai/api/v1/objects/types/%7Btype%7D",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200

Empty answer.

GET/objects/{type}/records

List records

The records of a kind (by key or id), newest change first, each with links (how many contacts, companies, deals… it links to).

Scope: read

Path parameters

typestringrequired
Path parameter.

Query parameters

qstring
Search in the name.
ownerstring
Owner email.
sortstring
name or updated_at (default).
limitinteger
1–1000, default 500.
offsetinteger
Rows to skip.
Request
curl "https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "type": {
    "key": "shops",
    "name": "Shop",
    "plural": "Shops"
  },
  "records": [
    {
      "id": "…",
      "name": "Galeries Lafayette — Haussmann",
      "values": {
        "city": "Paris",
        "format": "Flagship"
      },
      "owner_email": "lea@acme.com",
      "links": {
        "company": 1,
        "contact": 2
      },
      "updated_at": "2026-10-26T09:00:00Z"
    }
  ],
  "total": 1
}
POST/objects/{type}/records

Create a record

Values are checked against the properties (numbers, dates, choices, required ones).

Scope: write

Path parameters

typestringrequired
Path parameter.

Body

namestringrequired
Name.
valuesobject
Values by property key.
owner_emailstring
Owner (default: the key’s user).
linksobject[]
[{ entity_type, entity_id }] to link it at once.
Request
curl -X POST "https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Galeries Lafayette — Haussmann",
    "values": {
      "city": "Paris",
      "format": "Flagship"
    },
    "links": [
      {
        "entity_type": "company",
        "entity_id": "5b0c1d2e-3f40-4a5b-8c6d-7e8f9a0b1c2d"
      }
    ]
  }'
const res = await fetch("https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "name": "Galeries Lafayette — Haussmann",
    "values": {
      "city": "Paris",
      "format": "Flagship"
    },
    "links": [
      {
        "entity_type": "company",
        "entity_id": "5b0c1d2e-3f40-4a5b-8c6d-7e8f9a0b1c2d"
      }
    ]
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://app.meetzy.ai/api/v1/objects/%7Btype%7D/records",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "name": "Galeries Lafayette — Haussmann",
        "values": {
            "city": "Paris",
            "format": "Flagship"
        },
        "links": [
            {
                "entity_type": "company",
                "entity_id": "5b0c1d2e-3f40-4a5b-8c6d-7e8f9a0b1c2d"
            }
        ]
    },
)
data = res.json()
Response201

Empty answer.

GET/objects/records/{id}

Get a record

The record, its kind, what it links to (links, each with the contact, company, deal or record) and the records of other kinds linked to it (linked_from).

Scope: read

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200

Empty answer.

PATCH/objects/records/{id}

Update a record

values are merged (send only what changes; null clears one).

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).

Body

namestring
Name.
valuesobject
Values to change.
owner_emailstring
Owner.
Request
curl -X PATCH "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "values": {
      "format": "Corner"
    }
  }'
const res = await fetch("https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "PATCH",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "values": {
      "format": "Corner"
    }
  }),
});
const data = await res.json();
import os, requests

res = requests.patch(
    "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "values": {
            "format": "Corner"
        }
    },
)
data = res.json()
Response200

Empty answer.

DELETE/objects/records/{id}

Delete a record

With its links.

Scope: delete

Path parameters

idstringrequired
Id of the record (UUID).
Request
curl -X DELETE "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.delete(
    "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200

Empty answer.

POST/objects/records/{id}/links

Link a record

To a contact, company, deal or record of another kind (if its kind allows it). Linking twice does nothing.

Scope: write

Path parameters

idstringrequired
Id of the record (UUID).

Body

entity_typestringrequired
contact, company, deal or record.
entity_iduuidrequired
Its id.
labelstring
What the link means (e.g. Store manager).
Request
curl -X POST "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc/links" \
  -H "Authorization: Bearer $MEETZY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entity_type": "contact",
    "entity_id": "e43414d6-f56f-42be-a64c-a836d6015efc",
    "label": "Store manager"
  }'
const res = await fetch("https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc/links", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "entity_type": "contact",
    "entity_id": "e43414d6-f56f-42be-a64c-a836d6015efc",
    "label": "Store manager"
  }),
});
const data = await res.json();
import os, requests

res = requests.post(
    "https://app.meetzy.ai/api/v1/objects/records/e43414d6-f56f-42be-a64c-a836d6015efc/links",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
    json={
        "entity_type": "contact",
        "entity_id": "e43414d6-f56f-42be-a64c-a836d6015efc",
        "label": "Store manager"
    },
)
data = res.json()
Response201

Empty answer.

GET/objects/linked

Records linked to a contact, company or deal

Grouped by kind.

Scope: read

Query parameters

entity_typestringrequired
contact, company, deal or record.
entity_iduuidrequired
Its id.
Request
curl "https://app.meetzy.ai/api/v1/objects/linked" \
  -H "Authorization: Bearer $MEETZY_API_KEY"
const res = await fetch("https://app.meetzy.ai/api/v1/objects/linked", {
  headers: { Authorization: `Bearer ${process.env.MEETZY_API_KEY}` },
});
const data = await res.json();
import os, requests

res = requests.get(
    "https://app.meetzy.ai/api/v1/objects/linked",
    headers={"Authorization": f"Bearer {os.environ['MEETZY_API_KEY']}"},
)
data = res.json()
Response200
{
  "groups": [
    {
      "type": {
        "key": "shops",
        "name": "Shop",
        "plural": "Shops"
      },
      "records": [
        {
          "id": "…",
          "name": "Galeries Lafayette — Haussmann",
          "values": {
            "city": "Paris"
          },
          "link_id": "…"
        }
      ]
    }
  ]
}