Views API
Every Views action (5) and data model (2): endpoints, scopes, input, preconditions, events and examples.
Saved lists — the columns, filters and order you chose.
Module code view_grid · 5 actions · 2 data models · 3 events. A key or token never does more here than the person behind it can; row-level security applies exactly as in the app. Scopes: view_grid (everything), view_grid:read (read only) or view_grid:<capability>.
Resources
| Resource | Table | List and read | POST | PATCH | DELETE |
|---|---|---|---|---|---|
saved_views | saved_view | /api/v1/saved_views | |||
view_states | view_state | /api/v1/view_states |
Lists take limit (up to 200), cursor, order (e.g. -created_at), fields and q; every other query parameter is a column filter: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.
Actions
| Action | Needs | What it does |
|---|---|---|
view_grid.copy_base_views | view_grid:write | Copy Base views |
view_grid.delete | view_grid:write | Delete a view |
view_grid.remember | view_grid:read | Remember where I left this list |
view_grid.save | view_grid:write | Save this view |
view_grid.update | view_grid:write | Change a saved view |
view_grid.copy_base_views
Copy Base views — Copies shared views and your personal views onto copied Base tables.
Needs view_grid:write · changes data
https://app.getera.io/api/v1/saved_views/actions/copy_base_views- Canonical address:
POST /api/v1/actions/view_grid.copy_base_views
Input
| Field | Type | Required | Notes |
|---|---|---|---|
tableMap | object / array | yes | Table identities |
columnMap | object / array | yes | Field identities |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
invalid_shape | Identity maps must contain UUID pairs. |
Events it publishes: view_grid.saved
What it writes: saved_view (insert) — Copies visible views onto the copied tables
curl -X POST https://app.getera.io/api/v1/saved_views/actions/copy_base_views \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"tableMap":{},"columnMap":{}}'{
"ok": true,
"result": "…",
"events": [
"view_grid.saved"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.savedViews.copyBaseViews({
tableMap: {},
columnMap: {}
})era saved_views copy_base_views --data '{"tableMap":{},"columnMap":{}}'{
"name": "era__view_grid__copy_base_views",
"arguments": {
"tableMap": {},
"columnMap": {}
}
}Errors: 401 no or expired credential · 403 the credential does not hold view_grid:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 invalid_shape · 429 slow down
view_grid.delete
Delete a view — Removes a saved view.
Needs view_grid:write · removes or cannot be undone · asks a person to confirm when Era runs it
https://app.getera.io/api/v1/saved_views/actions/delete- Canonical address:
POST /api/v1/actions/view_grid.delete
Input
| Field | Type | Required | Notes |
|---|---|---|---|
view_id | uuid | yes | View |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
not_found | That view is not on this workspace. |
not_yours | A shared view can only be removed by a manager. |
Events it publishes: view_grid.deleted
What it writes: saved_view (delete) — Deletes the view
curl -X POST https://app.getera.io/api/v1/saved_views/actions/delete \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"view_id":"VIEW_ID"}'{
"ok": true,
"result": "…",
"events": [
"view_grid.deleted"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.savedViews.delete({
view_id: "VIEW_ID"
})era saved_views delete \
--view-id "VIEW_ID"{
"name": "era__view_grid__delete",
"arguments": {
"view_id": "VIEW_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold view_grid:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found, not_yours · 429 slow down
view_grid.remember
Remember where I left this list — Stores one person’s unsaved arrangement of one list.
Needs view_grid:read · changes data
https://app.getera.io/api/v1/view_states/actions/remember- Canonical address:
POST /api/v1/actions/view_grid.remember
Input
| Field | Type | Required | Notes |
|---|---|---|---|
module_code | string | yes | Module · max 41 |
view_key | string | yes | List · max 80 |
state | string | yes | Arrangement |
saved_view_id | uuid | Based on |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
unknown_module | No such module. |
invalid_shape | The arrangement must be an object. |
What it writes: view_state (update) — Stores the arrangement
curl -X POST https://app.getera.io/api/v1/view_states/actions/remember \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"module_code":"Module","view_key":"List","state":"Arrangement"}'{
"ok": true,
"result": "…",
"events": []
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.viewStates.remember({
module_code: "Module",
view_key: "List",
state: "Arrangement"
})era view_states remember \
--module-code "Module" \
--view-key "List" \
--state "Arrangement"{
"name": "era__view_grid__remember",
"arguments": {
"module_code": "Module",
"view_key": "List",
"state": "Arrangement"
}
}Errors: 401 no or expired credential · 403 the credential does not hold view_grid:read · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 unknown_module, invalid_shape · 429 slow down
view_grid.save
Save this view — Names the current arrangement of a list so it can be returned to.
Needs view_grid:write · changes data
https://app.getera.io/api/v1/saved_views/actions/save- Canonical address:
POST /api/v1/actions/view_grid.save
Input
| Field | Type | Required | Notes |
|---|---|---|---|
module_code | string | yes | Module · max 41 |
view_key | string | yes | List · max 80 |
name | string | yes | Name · max 80 |
kind | string (enum) | Kind · Allowed values: grid, kanban, gallery, calendar, timeline, form, map | |
columns | string | Columns | |
sorts | string | Sorting | |
conditions | string | Filter | |
options | string | Options | |
shared | boolean | Share with the workspace · Everyone sees it. Only a manager can publish one. | |
is_default | boolean | Open this list with it |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
unknown_module | No such module. |
invalid_shape | The arrangement is not in the expected shape. |
name_taken | A view with that name already exists on this list. |
cannot_share | Sharing a view with the workspace needs manage. |
Events it publishes: view_grid.saved, view_grid.shared
What it writes: saved_view (insert) — Saves the view
curl -X POST https://app.getera.io/api/v1/saved_views/actions/save \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"module_code":"Module","view_key":"List","name":"Name"}'{
"ok": true,
"result": "…",
"events": [
"view_grid.saved",
"view_grid.shared"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.savedViews.save({
module_code: "Module",
view_key: "List",
name: "Name"
})era saved_views save \
--module-code "Module" \
--view-key "List" \
--name "Name"{
"name": "era__view_grid__save",
"arguments": {
"module_code": "Module",
"view_key": "List",
"name": "Name"
}
}Errors: 401 no or expired credential · 403 the credential does not hold view_grid:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 unknown_module, invalid_shape, name_taken, cannot_share · 429 slow down
view_grid.update
Change a saved view — Renames a view, or stores the arrangement it is currently showing.
Needs view_grid:write · changes data
https://app.getera.io/api/v1/saved_views/actions/update- Canonical address:
POST /api/v1/actions/view_grid.update
Input
| Field | Type | Required | Notes |
|---|---|---|---|
view_id | uuid | yes | View |
name | string | Name · max 80 | |
columns | string | Columns | |
sorts | string | Sorting | |
conditions | string | Filter | |
options | string | Options | |
is_default | boolean | Open this list with it |
Preconditions
The action is refused with 409 and one of these codes:
| Code | Refused when |
|---|---|
not_found | That view is not on this workspace. |
not_yours | A shared view can only be changed by a manager. |
invalid_shape | The arrangement is not in the expected shape. |
name_taken | A view with that name already exists on this list. |
no_change | Something has to change. |
view_locked | A locked view cannot be changed until a manager unlocks it. |
Events it publishes: view_grid.saved
What it writes: saved_view (update) — Rewrites the view
curl -X POST https://app.getera.io/api/v1/saved_views/actions/update \
-H "Authorization: Bearer $ERA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"view_id":"VIEW_ID"}'{
"ok": true,
"result": "…",
"events": [
"view_grid.saved"
]
}import { createEra } from "@getera/sdk"
const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.savedViews.update({
view_id: "VIEW_ID"
})era saved_views update \
--view-id "VIEW_ID"{
"name": "era__view_grid__update",
"arguments": {
"view_id": "VIEW_ID"
}
}Errors: 401 no or expired credential · 403 the credential does not hold view_grid:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_found, not_yours, invalid_shape, name_taken, no_change, view_locked · 429 slow down
Data models
SavedView
Table saved_view · Resource saved_views
GET /api/v1/saved_viewsGET /api/v1/saved_views/{id}
| Column | Type | Nullable | Allowed values | References |
|---|---|---|---|---|
id | string (uuid) · uuid | |||
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
module_code | string · text | module | ||
view_key | string · text | |||
name | string · text | |||
owner_id | string (uuid) · uuid | yes | app_user | |
is_default | boolean · bool | |||
columns | object · jsonb | |||
sorts | object · jsonb | |||
conditions | object · jsonb | |||
options | object · jsonb | |||
created_at | string (date-time) · timestamptz | |||
updated_at | string (date-time) · timestamptz | |||
kind | string · text | grid, kanban, gallery, calendar, timeline, form, map |
Primary key: id
Checks:
CHECK ((jsonb_typeof(columns) = 'array'::text))CHECK ((jsonb_typeof(conditions) = 'object'::text))CHECK ((jsonb_typeof(options) = 'object'::text))CHECK ((jsonb_typeof(sorts) = 'array'::text))
ViewState
Table view_state · Resource view_states
GET /api/v1/view_statesGET /api/v1/view_states/{id}
| Column | Type | Nullable | Allowed values | References |
|---|---|---|---|---|
organization_id | string (uuid) · uuid | organization | ||
workspace_id | string (uuid) · uuid | workspace | ||
user_id | string (uuid) · uuid | app_user | ||
module_code | string · text | module | ||
view_key | string · text | |||
saved_view_id | string (uuid) · uuid | yes | saved_view | |
state | object · jsonb | |||
updated_at | string (date-time) · timestamptz |
Primary key: workspace_id, user_id, module_code, view_key
Checks:
CHECK ((jsonb_typeof(state) = 'object'::text))
Events
Workflows and webhooks react to these events.
| Event | What happens | Payload |
|---|---|---|
view_grid.deleted | A view was deleted. | view_id |
view_grid.saved | A view was saved. | view_id, name |
view_grid.shared | A private view was published to the workspace. | view_id |