> For the complete documentation index, see [llms.txt](https://docs.ninox.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ninox.com/ninox-api/api-reference/api-endpoints/workspace.md).

# Workspace

## Get schema changes since a timestamp

> Retrieves the log of changes to modules, tables, and fields since a given timestamp, for incremental sync. One entry per recorded change, oldest first, so an object edited three times in the window appears three times. Pass the response's \`meta.asOf\` as \`since\` on the next poll to avoid gaps or duplicates. When paging through one poll with \`limit\`/\`offset\`, also pass the first page's \`meta.asOf\` back as \`asOf\` on every subsequent page of that same poll. Changes older than \`meta.retentionCutoff\` are no longer available; fetch the full schema instead.

```json
{"openapi":"3.0.0","info":{"title":"Ninox Public API","version":"1.0.0"},"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"API Key","description":"Enter your Workspace API key. \n\n API keys can be generated and managed within the **Workspace Integration** settings in the Ninox app.","in":"header","name":"Authorization","type":"http"}},"schemas":{"SchemaChangesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string","enum":["created","deleted","restored","updated"],"description":"What happened to the object"},"changedAt":{"type":"string","description":"When the change happened (ISO 8601)"},"id":{"type":"string","description":"Object id"},"kind":{"type":"string","enum":["Field","Module","Table"],"description":"Kind of schema object"}},"required":["action","changedAt","id","kind"]},"description":"One entry per recorded change, oldest first"},"meta":{"type":"object","properties":{"asOf":{"type":"string","description":"Server timestamp to pass as `since` on the next poll"},"retentionCutoff":{"type":"string","description":"Oldest change still readable under the workspace plan (ISO 8601), or null for unlimited retention. A `since` older than this has gaps — do a full schema fetch instead","nullable":true}}},"page_info":{"type":"object","properties":{"has_more":{"type":"boolean","description":"Whether more results are available"},"limit":{"type":"number","description":"Maximum results per page"},"offset":{"type":"number","description":"Current offset"}},"description":"Pagination information"}},"required":["data","meta","page_info"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string","description":"Error message"}}}},"required":["error"]}}},"paths":{"/api/v1/workspace/{workspaceId}/schema/changes":{"get":{"operationId":"WorkspacesV1Controller_getSchemaChanges","summary":"Get schema changes since a timestamp","description":"Retrieves the log of changes to modules, tables, and fields since a given timestamp, for incremental sync. One entry per recorded change, oldest first, so an object edited three times in the window appears three times. Pass the response's `meta.asOf` as `since` on the next poll to avoid gaps or duplicates. When paging through one poll with `limit`/`offset`, also pass the first page's `meta.asOf` back as `asOf` on every subsequent page of that same poll. Changes older than `meta.retentionCutoff` are no longer available; fetch the full schema instead.","parameters":[{"name":"workspaceId","required":true,"in":"path","description":"Workspace ID","schema":{"minLength":12,"maxLength":12,"pattern":"^[a-z0-9]+$","type":"string"}},{"name":"asOf","required":false,"in":"query","description":"Pin the poll window to this timestamp (a prior response's `meta.asOf`) when fetching page 2+ of the same poll; omit on the first page","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of changes to return (1-100)","schema":{"minimum":1,"maximum":100,"type":"number"}},{"name":"offset","required":false,"in":"query","description":"Number of changes to skip (starts with 0)","schema":{"minimum":0,"maximum":9007199254740991,"type":"number"}},{"name":"since","required":true,"in":"query","description":"Return changes at or after this ISO 8601 timestamp","schema":{"format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$","type":"string"}}],"responses":{"200":{"description":"Schema changes retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchemaChangesResponse"}}}},"400":{"description":"Bad request (missing `since`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workspace not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["Workspace"]}}}}
```

## Get workspace details

> Retrieves comprehensive details about a workspace, including all its modules

```json
{"openapi":"3.0.0","info":{"title":"Ninox Public API","version":"1.0.0"},"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"API Key","description":"Enter your Workspace API key. \n\n API keys can be generated and managed within the **Workspace Integration** settings in the Ninox app.","in":"header","name":"Authorization","type":"http"}},"schemas":{"WorkspaceResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"modules":{"type":"array","items":{"type":"object","properties":{"afterOpen":{"description":"Script expression run in the browser each time the app is opened","type":"string"},"components":{"description":"Module components (pages, containers, widgets). Read-only.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Component id"},"kind":{"type":"string","description":"Component type (e.g. Container, Button, Text, Page)"},"name":{"description":"Component name","type":"string"},"order":{"description":"Component display order","type":"number"},"parentId":{"description":"Parent component id (forms the component tree)","type":"string"},"visible":{"description":"Conditional visibility logic: a boolean, or a script expression (as { $nx: <script> }) evaluated at render time. Read-only.","anyOf":[{"type":"boolean"},{"type":"object","properties":{"$nx":{"type":"string","description":"Script expression"}},"required":["$nx"]}]}},"required":["id","kind"]}},"hideNavigation":{"description":"Hide module from navigation","type":"boolean"},"icon":{"description":"Module icon","type":"object","properties":{"color":{"description":"Icon color (hex string)","type":"string"},"filling":{"description":"Icon filling","anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]}]},"icon":{"type":"string","description":"Icon name"}},"required":["icon"]},"isHidden":{"description":"Hide module","type":"boolean"},"labels":{"description":"Module labels (localized)","type":"object","additionalProperties":{"type":"string"}},"name":{"type":"string"},"openRoles":{"description":"Module open roles","type":"array","items":{"type":"string"}},"tables":{"type":"array","items":{"type":"object","properties":{"canCreate":{"description":"Script expression gating record creation","type":"string"},"canDelete":{"description":"Script expression gating record deletion","type":"string"},"canRead":{"description":"Script expression gating record read access","type":"string"},"canWrite":{"description":"Script expression gating record write access","type":"string"},"createRoles":{"description":"Roles allowed to create records","type":"array","items":{"type":"string"}},"deleteRoles":{"description":"Roles allowed to delete records","type":"array","items":{"type":"string"}},"fields":{"type":"array","items":{"type":"object","properties":{"binding":{"description":"Read-only: internal binding reference, format not yet specified","type":"string"},"canRead":{"description":"Script expression gating field-level read access","type":"string"},"canWrite":{"description":"Script expression gating field-level write access","type":"string"},"defaultValue":{"description":"Default value applied when a record is created: a literal value (an array of option ids for multi/dmulti), or a script expression (as { $nx: <script> }) evaluated at creation time","anyOf":[{"type":"object","properties":{"$nx":{"type":"string","description":"Script expression"}},"required":["$nx"]},{"anyOf":[{"type":"boolean"},{"type":"number"},{"type":"string"}],"nullable":true},{"type":"array","items":{"type":"string"}}]},"expression":{"description":"Expression (for function type)","type":"string"},"expressionErrors":{"description":"Expression validation errors (for function type)","type":"array","items":{"type":"object","properties":{"column":{"type":"number","description":"Column number where the error occurred"},"line":{"type":"number","description":"Line number where the error occurred"},"message":{"type":"string","description":"Error message"}},"required":["column","line","message"]}},"index":{"description":"Field is indexed","type":"boolean"},"labels":{"description":"Field labels (localized)","type":"object","additionalProperties":{"type":"string"}},"name":{"type":"string","description":"Field name"},"onUpdate":{"description":"Script expression run as a row trigger when the field value changes","type":"string"},"optionColor":{"description":"Color expression for dchoice/dmulti fields","type":"string"},"optionIcon":{"description":"Icon expression for dchoice/dmulti fields","type":"string"},"optionName":{"description":"Display name expression for dchoice/dmulti fields","type":"string"},"options":{"description":"Options array for choice/multi fields, or selection expression for dchoice/dmulti fields","anyOf":[{"type":"array","items":{"type":"object","properties":{"color":{"description":"Option color (hex string)","type":"string"},"icon":{"description":"Option icon name","type":"string"},"id":{"type":"string","description":"Stable option id"},"labels":{"description":"Localized option labels","type":"object","additionalProperties":{"type":"string"}},"name":{"type":"string","description":"Option name"},"order":{"type":"number","description":"Option display order"},"textColor":{"description":"Option text color (hex string)","type":"string"}},"required":["id","name","order"]}},{"type":"string"}]},"readRoles":{"description":"Roles allowed to read the field","type":"array","items":{"type":"string"}},"refTableId":{"description":"Reference table id","type":"string"},"required":{"description":"Field is required","type":"boolean"},"search":{"description":"Field is searchable","type":"boolean"},"syncedFrom":{"description":"Source column this field syncs from. Read-only unless the table has two-way sync with updates enabled, in which case every synced field except the key column is writable.","type":"string"},"type":{"type":"string","enum":["any","appointment","boolean","choice","color","date","dchoice","dmulti","file","function","html","icon","lambda","multi","number","react","reference","reverse","rowId","string","styled","time","timeinterval","timestamp","unknown","user","void"],"description":"Field type"},"unique":{"description":"Field is unique","type":"boolean"},"variant":{"description":"Field variant (for string type)","type":"string"},"writeRoles":{"description":"Roles allowed to write to the field","type":"array","items":{"type":"string"}}},"required":["name","type"]}},"hasFiles":{"description":"Enable files for the table","type":"boolean"},"hasGlobalSearch":{"description":"Enable global search for the table","type":"boolean"},"hasHistory":{"description":"Enable history for the table","type":"boolean"},"icon":{"description":"Table icon","type":"object","properties":{"color":{"description":"Icon color (hex string)","type":"string"},"filling":{"description":"Icon filling","anyOf":[{"type":"number","enum":[0]},{"type":"number","enum":[1]}]},"icon":{"type":"string","description":"Icon name"}},"required":["icon"]},"isEmailLinkingEnabled":{"description":"Enable email linking for the table","type":"boolean"},"isHidden":{"description":"Hide the table","type":"boolean"},"labels":{"description":"Table labels (localized)","type":"object","additionalProperties":{"type":"string"}},"name":{"type":"string"},"onCreate":{"description":"Script expression run as a trigger after a record is created","type":"string"},"onDelete":{"description":"Script expression run as a trigger when a record is deleted","type":"string"},"onUpdate":{"description":"Script expression run as a trigger after a record is updated","type":"string"},"readRoles":{"description":"Roles allowed to read records","type":"array","items":{"type":"string"}},"writeRoles":{"description":"Roles allowed to update records","type":"array","items":{"type":"string"}}},"required":["name"]}}},"required":["name"]}},"name":{"type":"string"}},"description":"Workspace details"}},"required":["data"]},"ErrorResponse":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string","description":"Error message"}}}},"required":["error"]}}},"paths":{"/api/v1/workspace/{workspaceId}":{"get":{"operationId":"WorkspacesV1Controller_getWorkspace","summary":"Get workspace details","description":"Retrieves comprehensive details about a workspace, including all its modules","parameters":[{"name":"workspaceId","required":true,"in":"path","description":"Workspace ID","schema":{"minLength":12,"maxLength":12,"pattern":"^[a-z0-9]+$","type":"string"}}],"responses":{"200":{"description":"Workspace details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workspace not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"tags":["Workspace"]}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ninox.com/ninox-api/api-reference/api-endpoints/workspace.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
