{
  "schemaVersion": "1.0",
  "title": "Twenty workspace metadata",
  "description": "Use these five operations to read or change one of twelve fixed Twenty metadata resource types. The connector selects the route from a closed resource enum and applies resource-specific list-query guards.",
  "canonical": "https://getaip.org/docs/connectors/twenty/capabilities/workspace-metadata",
  "route": "/docs/connectors/twenty/capabilities/workspace-metadata",
  "source": "docs/connectors/twenty/capabilities/workspace-metadata.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/twenty/capabilities/workspace-metadata.md",
    "txt": "/docs/download/connectors/twenty/capabilities/workspace-metadata.txt",
    "json": "/docs/download/connectors/twenty/capabilities/workspace-metadata.json",
    "pdf": "/docs/download/connectors/twenty/capabilities/workspace-metadata.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Twenty workspace metadata\ndescription: >-\n  Reference fixed metadata resources, resource-specific queries, mutations, and\n  host-owned webhook-secret handling\nkind: capability-reference\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: twenty\ncapabilityIds:\n  - cap:twenty:metadata.list\n  - cap:twenty:metadata.get\n  - cap:twenty:metadata.create\n  - cap:twenty:metadata.update\n  - cap:twenty:metadata.delete\n---\n\n# Twenty workspace metadata\n\nUse these five operations to read or change one of twelve fixed Twenty\nmetadata resource types. The connector selects the route from a closed\nresource enum and applies resource-specific list-query guards.\n\nMetadata changes can alter schema, views, layouts, and webhook delivery policy.\nAll three mutations are critical, approval-required, idempotency-required,\nunsafe to retry, and unsupported by rollback or compensation.\n\n## Supported resources\n\n| Resource | Purpose | List query |\n|---|---|---|\n| `objects` | Object definitions | `limit`, `starting_after`, `ending_before` |\n| `fields` | Field definitions | `limit`, `starting_after`, `ending_before` |\n| `views` | Saved views | Optional `objectMetadataId` |\n| `viewFields` | View field membership | Optional `viewId` |\n| `viewFilters` | View filter definitions | Optional `viewId` |\n| `viewGroups` | View grouping definitions | Optional `viewId` |\n| `viewSorts` | View sort definitions | Optional `viewId` |\n| `viewFilterGroups` | Nested view filter groups | Optional `viewId` |\n| `pageLayouts` | Record, index, dashboard, or standalone layouts | Optional object and type pair |\n| `pageLayoutTabs` | Tabs under one layout | Required `pageLayoutId` |\n| `pageLayoutWidgets` | Widgets under one tab | Required `pageLayoutTabId` |\n| `webhooks` | Provider webhook registrations | No query |\n\nAny other `resource` value fails before provider dispatch. The connector does\nnot expose a caller-selected metadata path.\n\n## Compare the operations\n\n| Operation | Provider request | Risk | Required input |\n|---|---|---|---|\n| `metadata.list` | `GET /rest/metadata/{resource}` | Low | `resource` |\n| `metadata.get` | `GET /rest/metadata/{resource}/{id}` | Low | `resource`, `id` |\n| `metadata.create` | `POST /rest/metadata/{resource}` | Critical | `resource`, object `body` |\n| `metadata.update` | `PATCH /rest/metadata/{resource}/{id}` | Critical | `resource`, `id`, object `body` |\n| `metadata.delete` | `DELETE /rest/metadata/{resource}/{id}` | Critical | `resource`, `id` |\n\nThe two reads need no approval, accept an optional key, and advertise safe\nretry. Every mutation requires approval and a key and advertises unsafe retry.\n\nAll five support synchronous execution only. None supports asynchronous\nexecution, streaming, cancellation, transactions, reconciliation, or\ncompensation.\n\n## List metadata\n\n`cap:twenty:metadata.list` accepts the selected resource and only its allowed\nquery keys.\n\nList object definitions with bounded pagination:\n\n```json\n{\n  \"resource\": \"objects\",\n  \"query\": {\n    \"limit\": 50,\n    \"starting_after\": \"0190c42f-2d5a-7000-8000-000000000050\"\n  }\n}\n```\n\n`limit` accepts `0` through `200`. Both cursors must be RFC 4122 UUIDs with\nversion 1 through 5 when present.\n\nList view fields for one view:\n\n```json\n{\n  \"resource\": \"viewFields\",\n  \"query\": {\n    \"viewId\": \"0190c42f-2d5a-7000-8000-000000000051\"\n  }\n}\n```\n\n`viewId` is optional for the five view-child resource types. An omitted value\ncan yield a wider provider result; deployment policy should require the\nnarrowest useful scope.\n\nList page layouts for an object and type:\n\n```json\n{\n  \"resource\": \"pageLayouts\",\n  \"query\": {\n    \"objectMetadataId\": \"0190c42f-2d5a-7000-8000-000000000052\",\n    \"pageLayoutType\": \"RECORD_PAGE\"\n  }\n}\n```\n\nAllowed layout types are `RECORD_INDEX`, `RECORD_PAGE`, `DASHBOARD`, and\n`STANDALONE_PAGE`. A supplied type requires `objectMetadataId` because the\npinned provider otherwise ignores it.\n\n`pageLayoutTabs` requires `pageLayoutId`. `pageLayoutWidgets` requires\n`pageLayoutTabId`. Both values must pass the UUID validator.\n\nThe `webhooks` resource accepts no query. Unknown or resource-inapplicable keys\nfail before provider dispatch.\n\n## Get one metadata resource\n\n`cap:twenty:metadata.get` accepts a supported resource and UUID:\n\n```json\n{\n  \"resource\": \"fields\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000053\"\n}\n```\n\nNo query object is accepted. The connector sends the fixed workspace token and\nreturns provider JSON without resource-specific normalization.\n\n## Create metadata\n\n`cap:twenty:metadata.create` accepts a supported resource and object body:\n\n```json\n{\n  \"resource\": \"views\",\n  \"body\": {\n    \"name\": \"AIP Review View\",\n    \"objectMetadataId\": \"0190c42f-2d5a-7000-8000-000000000052\"\n  }\n}\n```\n\nThe outer schema permits at most 2,048 top-level body properties, and the\nserialized request cannot exceed 16 MiB. Twenty validates resource-specific\nfields and relationships.\n\nCreate requires critical-action approval and a stable idempotency key. The\nconnector does not synthesize metadata IDs or force provider upsert.\n\n## Update metadata\n\n`cap:twenty:metadata.update` requires resource, target UUID, and object body:\n\n```json\n{\n  \"resource\": \"views\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000054\",\n  \"body\": {\n    \"name\": \"AIP Approved View\"\n  }\n}\n```\n\nNo query object is accepted. The connector does not reject an empty body at\nits outer layer; policy should require a reviewed, meaningful change.\n\n## Delete metadata\n\n`cap:twenty:metadata.delete` accepts only resource and target UUID:\n\n```json\n{\n  \"resource\": \"views\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000054\"\n}\n```\n\nDeletion is critical and has no connector rollback. Preflight dependent fields,\nviews, layout children, automations, and webhook ownership through current\nprovider reads before approval.\n\n## Handle webhook metadata secrets\n\nThe `webhooks` metadata resource has an additional secret boundary. An Action\nbody cannot contain a field named `secret` for create or update.\n\nCreate one webhook registration without a secret field:\n\n```json\n{\n  \"resource\": \"webhooks\",\n  \"body\": {\n    \"targetUrl\": \"https://connector.example.test/webhooks/twenty\"\n  }\n}\n```\n\nCreate rejects `rotateConfiguredSecret` and injects the current host-owned\nwebhook secret. The operation fails when webhook security is not configured on\nthe host.\n\nRequest controlled secret rotation on an existing provider registration:\n\n```json\n{\n  \"resource\": \"webhooks\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000055\",\n  \"body\": {\n    \"rotateConfiguredSecret\": true\n  }\n}\n```\n\nUpdate removes the control field before provider dispatch and injects the\nconfigured secret only when its value is Boolean `true`. A value of `false`,\nanother type, or a caller-supplied `secret` is invalid.\n\nWhen the resource is `webhooks`, the connector recursively removes every\nresponse field named `secret`. This redaction applies to list, get, create,\nupdate, and delete results.\n\nThe redaction protects the provider response path. It does not replace log,\ntrace, database, secret-manager, or evidence redaction outside the connector.\n\n## Apply approval and idempotency\n\nCreate, update, and delete require a tenant-policy decision with reason, input\nsnapshot, and policy decision. The approval validity window is 900,000 ms.\n\nMutation keys accept 1 through 1,024 ASCII graphic bytes. The scope is the\nexternal account, collision behavior revalidates the input hash, and the\npublished TTL is 604,800,000 ms.\n\nBind approval and key to the exact resource, ID, body, fixed workspace,\ncredential revision, and expected dependency impact. Secret bytes remain\noutside approval input and evidence.\n\n## Interpret results and failures\n\nA completed result contains provider `http_status`, optional\n`provider_request_id`, and decoded provider `body`. The connector records its\nprovider-effect-committed checkpoint after a successful mutation response.\n\n| Condition | Read decision | Mutation decision |\n|---|---|---|\n| Invalid resource, UUID, query, body, secret field, or rotation flag | Correct input | Correct input under a new governed intent |\n| Provider `401` or `403` | Repair fixed credential | Repair binding; do not replay |\n| Provider `429` or `5xx` | Retryable | Unsafe and uncertain |\n| Transport failure | Retryable | Unsafe; may be uncertain after connection |\n| Oversized or invalid provider response | Not automatically retryable | Unsafe and uncertain |\n\nAll three metadata mutations advertise unsafe retry. Preserve original Action,\nkey, approval, and provider request identity and inspect current metadata before\nany recovery mutation.\n\n## Security and data boundaries\n\nAll five contracts classify data as confidential, possibly containing personal\ninformation, with redaction required. Metadata can disclose tenant schema,\nidentifiers, saved views, layouts, and event destinations.\n\nThe connector does not implement field-level metadata authorization, dependency\nanalysis, migration ordering, provider rollback, or workspace backup. Apply\nthose controls in deployment policy and the application workflow.\n\n## Related documentation\n\n- [Twenty capability index](README.md)\n- [Twenty connector configuration](../reference/configuration.md)\n- [Authentication and workspace isolation](../getting-started/authentication-and-workspace-isolation.md)\n- [Approvals and policy](../../../concepts/approvals-and-policy.md)\n- [Errors and retry decisions](../../../reference/errors.md)\n",
    "text": "Twenty workspace metadata\n\nUse these five operations to read or change one of twelve fixed Twenty\nmetadata resource types. The connector selects the route from a closed\nresource enum and applies resource-specific list-query guards.\n\nMetadata changes can alter schema, views, layouts, and webhook delivery policy.\nAll three mutations are critical, approval-required, idempotency-required,\nunsafe to retry, and unsupported by rollback or compensation.\n\nSupported resources\n\n| Resource | Purpose | List query |\n\n| objects | Object definitions | limit, startingafter, endingbefore |\n| fields | Field definitions | limit, startingafter, endingbefore |\n| views | Saved views | Optional objectMetadataId |\n| viewFields | View field membership | Optional viewId |\n| viewFilters | View filter definitions | Optional viewId |\n| viewGroups | View grouping definitions | Optional viewId |\n| viewSorts | View sort definitions | Optional viewId |\n| viewFilterGroups | Nested view filter groups | Optional viewId |\n| pageLayouts | Record, index, dashboard, or standalone layouts | Optional object and type pair |\n| pageLayoutTabs | Tabs under one layout | Required pageLayoutId |\n| pageLayoutWidgets | Widgets under one tab | Required pageLayoutTabId |\n| webhooks | Provider webhook registrations | No query |\n\nAny other resource value fails before provider dispatch. The connector does\nnot expose a caller-selected metadata path.\n\nCompare the operations\n\n| Operation | Provider request | Risk | Required input |\n\n| metadata.list | GET /rest/metadata/{resource} | Low | resource |\n| metadata.get | GET /rest/metadata/{resource}/{id} | Low | resource, id |\n| metadata.create | POST /rest/metadata/{resource} | Critical | resource, object body |\n| metadata.update | PATCH /rest/metadata/{resource}/{id} | Critical | resource, id, object body |\n| metadata.delete | DELETE /rest/metadata/{resource}/{id} | Critical | resource, id |\n\nThe two reads need no approval, accept an optional key, and advertise safe\nretry. Every mutation requires approval and a key and advertises unsafe retry.\n\nAll five support synchronous execution only. None supports asynchronous\nexecution, streaming, cancellation, transactions, reconciliation, or\ncompensation.\n\nList metadata\n\ncap:twenty:metadata.list accepts the selected resource and only its allowed\nquery keys.\n\nList object definitions with bounded pagination:\n\n{\n  \"resource\": \"objects\",\n  \"query\": {\n    \"limit\": 50,\n    \"startingafter\": \"0190c42f-2d5a-7000-8000-000000000050\"\n  }\n}\n\nlimit accepts 0 through 200. Both cursors must be RFC 4122 UUIDs with\nversion 1 through 5 when present.\n\nList view fields for one view:\n\n{\n  \"resource\": \"viewFields\",\n  \"query\": {\n    \"viewId\": \"0190c42f-2d5a-7000-8000-000000000051\"\n  }\n}\n\nviewId is optional for the five view-child resource types. An omitted value\ncan yield a wider provider result; deployment policy should require the\nnarrowest useful scope.\n\nList page layouts for an object and type:\n\n{\n  \"resource\": \"pageLayouts\",\n  \"query\": {\n    \"objectMetadataId\": \"0190c42f-2d5a-7000-8000-000000000052\",\n    \"pageLayoutType\": \"RECORDPAGE\"\n  }\n}\n\nAllowed layout types are RECORDINDEX, RECORDPAGE, DASHBOARD, and\nSTANDALONEPAGE. A supplied type requires objectMetadataId because the\npinned provider otherwise ignores it.\n\npageLayoutTabs requires pageLayoutId. pageLayoutWidgets requires\npageLayoutTabId. Both values must pass the UUID validator.\n\nThe webhooks resource accepts no query. Unknown or resource-inapplicable keys\nfail before provider dispatch.\n\nGet one metadata resource\n\ncap:twenty:metadata.get accepts a supported resource and UUID:\n\n{\n  \"resource\": \"fields\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000053\"\n}\n\nNo query object is accepted. The connector sends the fixed workspace token and\nreturns provider JSON without resource-specific normalization.\n\nCreate metadata\n\ncap:twenty:metadata.create accepts a supported resource and object body:\n\n{\n  \"resource\": \"views\",\n  \"body\": {\n    \"name\": \"AIP Review View\",\n    \"objectMetadataId\": \"0190c42f-2d5a-7000-8000-000000000052\"\n  }\n}\n\nThe outer schema permits at most 2,048 top-level body properties, and the\nserialized request cannot exceed 16 MiB. Twenty validates resource-specific\nfields and relationships.\n\nCreate requires critical-action approval and a stable idempotency key. The\nconnector does not synthesize metadata IDs or force provider upsert.\n\nUpdate metadata\n\ncap:twenty:metadata.update requires resource, target UUID, and object body:\n\n{\n  \"resource\": \"views\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000054\",\n  \"body\": {\n    \"name\": \"AIP Approved View\"\n  }\n}\n\nNo query object is accepted. The connector does not reject an empty body at\nits outer layer; policy should require a reviewed, meaningful change.\n\nDelete metadata\n\ncap:twenty:metadata.delete accepts only resource and target UUID:\n\n{\n  \"resource\": \"views\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000054\"\n}\n\nDeletion is critical and has no connector rollback. Preflight dependent fields,\nviews, layout children, automations, and webhook ownership through current\nprovider reads before approval.\n\nHandle webhook metadata secrets\n\nThe webhooks metadata resource has an additional secret boundary. An Action\nbody cannot contain a field named secret for create or update.\n\nCreate one webhook registration without a secret field:\n\n{\n  \"resource\": \"webhooks\",\n  \"body\": {\n    \"targetUrl\": \"https://connector.example.test/webhooks/twenty\"\n  }\n}\n\nCreate rejects rotateConfiguredSecret and injects the current host-owned\nwebhook secret. The operation fails when webhook security is not configured on\nthe host.\n\nRequest controlled secret rotation on an existing provider registration:\n\n{\n  \"resource\": \"webhooks\",\n  \"id\": \"0190c42f-2d5a-7000-8000-000000000055\",\n  \"body\": {\n    \"rotateConfiguredSecret\": true\n  }\n}\n\nUpdate removes the control field before provider dispatch and injects the\nconfigured secret only when its value is Boolean true. A value of false,\nanother type, or a caller-supplied secret is invalid.\n\nWhen the resource is webhooks, the connector recursively removes every\nresponse field named secret. This redaction applies to list, get, create,\nupdate, and delete results.\n\nThe redaction protects the provider response path. It does not replace log,\ntrace, database, secret-manager, or evidence redaction outside the connector.\n\nApply approval and idempotency\n\nCreate, update, and delete require a tenant-policy decision with reason, input\nsnapshot, and policy decision. The approval validity window is 900,000 ms.\n\nMutation keys accept 1 through 1,024 ASCII graphic bytes. The scope is the\nexternal account, collision behavior revalidates the input hash, and the\npublished TTL is 604,800,000 ms.\n\nBind approval and key to the exact resource, ID, body, fixed workspace,\ncredential revision, and expected dependency impact. Secret bytes remain\noutside approval input and evidence.\n\nInterpret results and failures\n\nA completed result contains provider httpstatus, optional\nproviderrequestid, and decoded provider body. The connector records its\nprovider-effect-committed checkpoint after a successful mutation response.\n\n| Condition | Read decision | Mutation decision |\n\n| Invalid resource, UUID, query, body, secret field, or rotation flag | Correct input | Correct input under a new governed intent |\n| Provider 401 or 403 | Repair fixed credential | Repair binding; do not replay |\n| Provider 429 or 5xx | Retryable | Unsafe and uncertain |\n| Transport failure | Retryable | Unsafe; may be uncertain after connection |\n| Oversized or invalid provider response | Not automatically retryable | Unsafe and uncertain |\n\nAll three metadata mutations advertise unsafe retry. Preserve original Action,\nkey, approval, and provider request identity and inspect current metadata before\nany recovery mutation.\n\nSecurity and data boundaries\n\nAll five contracts classify data as confidential, possibly containing personal\ninformation, with redaction required. Metadata can disclose tenant schema,\nidentifiers, saved views, layouts, and event destinations.\n\nThe connector does not implement field-level metadata authorization, dependency\nanalysis, migration ordering, provider rollback, or workspace backup. Apply\nthose controls in deployment policy and the application workflow.\n\nRelated documentation\n• Twenty capability index (README.md)\n• Twenty connector configuration (../reference/configuration.md)\n• Authentication and workspace isolation (../getting-started/authentication-and-workspace-isolation.md)\n• Approvals and policy (../../../concepts/approvals-and-policy.md)\n• Errors and retry decisions (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "3530c382990d953310b1fc2abb7062803d9dae6f14bf2faf9e2f4af176145c0c"
  }
}
