Overview

The Nimble REST API lets you interact with your workspace programmatically — create and update workitems, manage todos, log time, add comments, and more. This guide covers every available endpoint with example requests and responses for use with Postman.

Base URL: https://api.nimblework.com/blox/openapi

Getting a Token

Every API call requires Authorization: Bearer <token>. Register a client once, then request a new token whenever your token expires (~1 hour).

Step 1 — Register an API Client in Nimble

  1. Log in to your Nimble instance.
  2. In the left sidebar, click Account Space.
  3. In the top nav, click AdministrationREST API Client.
  4. Click + REGISTER (top right).
  5. Enter a Client Name. The Client ID is auto-generated — copy it.
  6. Expand Workspace Access Permissions and tick the permissions you need (Read Card, Create Card, Update Card, etc.).
  7. Click REGISTER CLIENT. Copy the Client Secret — it is shown only once. Click DONE.

Step 2 — Get a Token

POST https://api.nimblework.com/rest/v1/oauth/token

Header Value
Content-Type application/json

Body · raw · JSON

{
  "grant_type": "client_credentials",
  "client_id": "nmb_cli_xxxxxxxxxxxx",
  "client_secret": "your_client_secret_here"
}

Response 200 OK

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600
}

Copy the access_token. Use it as Bearer <access_token> in all subsequent requests.

Postman Setup

Create a Postman Environment with these variables so you only set them once:

Variable Example value
token eyJhbGciOiJSUzI1NiIs… (paste from Step 2)
baseUrl https://api.nimblework.com/blox/openapi
workspaceId 2110769
correlation INSTANCE:accountId:userId

Then in every request use {{baseUrl}}, {{token}}, etc.

Workspaces

GET — List Workspaces

GET {{baseUrl}}/workspaces?limit=10

Header Value
Authorization Bearer {{token}}
accept application/json
Param Required Description
limit opt Number of results per page (default 50)
pageToken opt Cursor from previous response for next page
sort opt Field to sort by
order opt asc or desc

Response 200 OK

{
  "items": [
    {
      "workspaceId": "2110769",
      "name": "My First Project",
      "description": "FromProjectCreate",
      "createdBy": "353147453",
      "modifiedBy": "353147453",
      "createdAt": "2026-08-14T17:12:17Z"
    }
  ],
  "total": 1,
  "pageToken": null
}

GET — Single Workspace

GET {{baseUrl}}/workspaces/:workspaceId

Header Value
Authorization Bearer {{token}}
accept application/json
Path Variable Required Description
workspaceId req e.g. 2110769

Response 200 OK

{
  "workspaceId": "2110769",
  "name": "My First Project",
  "description": "FromProjectCreate",
  "createdBy": "353147453",
  "modifiedBy": "353147453",
  "createdAt": "2026-08-14T17:12:17Z",
  "updatedAt": "2026-08-14T17:12:17Z"
}

Forms

Forms are the templates that define the fields for instances (workitems). Every instance belongs to a form. The X-WorkspaceId header is required for both form endpoints.

GET — List Forms

GET {{baseUrl}}/forms

Header Value
Authorization Bearer {{token}}
X-WorkspaceId {{workspaceId}}
accept application/json

Response 200 OK

{
  "items": [
    {
      "formId": "523440",
      "name": "Issue",
      "prefix": "ISS",
      "workspaceId": "2110769",
      "hexColorCode": "#FF5733",
      "custom": true,
      "createdAt": "2026-01-10T09:00:00Z",
      "fields": [
        { "fieldUniqueName": "Name",        "custom": false, "readOnly": false },
        { "fieldUniqueName": "Priority",     "custom": true,  "readOnly": false },
        { "fieldUniqueName": "Assigned To",  "custom": true,  "readOnly": false },
        { "fieldUniqueName": "Status",       "custom": false, "readOnly": true  }
      ]
    }
  ]
}

GET — Single Form (with full field schema)

GET {{baseUrl}}/forms/:formId

Header Value
Authorization Bearer {{token}}
X-WorkspaceId {{workspaceId}}
accept application/json
Path Variable Required Description
formId req Numeric form ID, e.g. 523440

Response 200 OK

{
  "formId": "523440",
  "name": "Issue",
  "prefix": "ISS",
  "workspaceId": "2110769",
  "fields": [
    {
      "fieldUniqueName": "Name",
      "custom": false,
      "readOnly": false,
      "type": "TEXT",
      "required": true
    },
    {
      "fieldUniqueName": "Priority",
      "custom": true,
      "readOnly": false,
      "type": "LOOKUP",
      "required": false
    }
  ]
}

Instances (Workitems)

An instance is a single workitem (card). Custom field values are sent and received at the root level alongside system fields. Always include formId in the request body for writes.

GET — List Instances

GET {{baseUrl}}/instances?workspaceId={{workspaceId}}&formId=523440&limit=20

Header Value
Authorization Bearer {{token}}
accept application/json
Param Required Description
workspaceId req Your workspace ID
formId opt Filter by form, e.g. 523440
expand opt true — inlines lookup field values
limit opt Max results per page
pageToken opt Cursor for next page
sort opt Field name to sort by
order opt asc or desc

Response 200 OK

{
  "items": [
    {
      "instanceId": "523440-42",
      "id": "ISS-42",
      "formId": "523440",
      "workspaceId": "2110769",
      "Name": "Login page broken",
      "Priority": "High",
      "Status": "Open",
      "createdAt": "2026-08-01T10:00:00Z"
    }
  ],
  "total": 1
}

GET — Single Instance

GET {{baseUrl}}/instances/:instanceId?expand=true

Header Value
Authorization Bearer {{token}}
accept application/json
Path Variable Required Description
instanceId req e.g. ISS-42

Response 200 OK

{
  "instanceId": "523440-42",
  "id": "ISS-42",
  "formId": "523440",
  "workspaceId": "2110769",
  "Name": "Login page broken",
  "Priority": "High",
  "Status": "Open",
  "flags": [],
  "blocks": [],
  "createdAt": "2026-08-01T10:00:00Z"
}

GET — Subblocks (child instances)

GET {{baseUrl}}/instances/:instanceId/subblocks?depth=-1

Header Value
Authorization Bearer {{token}}
accept application/json
Param Required Description
depth req 0 = direct children only · -1 = full tree · n = n levels

Response 200 OK

{
  "items": [
    { "instanceId": "523440-43", "id": "ISS-43", "Name": "Sub-task A", "...": "..." }
  ]
}

POST — Create Instance

POST {{baseUrl}}/instances

Header Value
Authorization Bearer {{token}}
Content-Type application/json
accept application/json
{
  "formId": "523440",
  "workspaceId": "2110769",
  "Name": "Login page broken",
  "Priority": "High",
  "Assigned To": "John Smith"
}

Note: formId and workspaceId are required. All other fields are custom fields from the form schema — use the exact field names returned by GET /forms/:formId.

Response 201 CREATED

{
  "instanceId": "523440-42",
  "id": "ISS-42"
}

The Location response header also contains the URL of the new instance.

PUT — Full Replace

PUT {{baseUrl}}/instances/:instanceId

Header Value
Authorization Bearer {{token}}
Content-Type application/json
accept application/json
{
  "formId": "523440",
  "Name": "Login page broken — updated",
  "Priority": "Critical"
}

Important: This is a full replacement. Any custom field not included in the body (e.g. Assigned To) will be cleared. System fields like Status, flags, and blocks are never cleared by PUT.

Response 200 OK

{
  "instanceId": "523440-42",
  "id": "ISS-42",
  "Name": "Login page broken — updated",
  "Priority": "Critical",
  "Assigned To": null
}

PATCH — Partial Update

PATCH {{baseUrl}}/instances/:instanceId

Header Value
Authorization Bearer {{token}}
Content-Type application/json
accept application/json
{
  "formId": "523440",
  "Priority": "Low"
}

Note: Only Priority changes. All other fields remain untouched. formId is required. Do not send flag or block keys here — use the dedicated sub-resource endpoints.

Response 200 OK

{
  "instanceId": "523440-42",
  "id": "ISS-42",
  "Priority": "Low"
}

DELETE — Delete Instance

DELETE {{baseUrl}}/instances/:instanceId

Header Value
Authorization Bearer {{token}}

Response 204 NO CONTENT — Empty body. Returns 404 if the instance has already been deleted.

Flags

Only available on instances of STANDALONE form types. Returns 400 for sub-block instances.

POST — Flag an Instance

POST {{baseUrl}}/instances/:instanceId/flags

Header Value
Authorization Bearer {{token}}
Content-Type application/json
accept */*
{
  "comment": "Needs immediate attention"
}

comment is optional. Max 5,000 characters if provided.

Response 200 OK

{
  "instanceId": "523440-42",
  "flags": [
    {
      "actionId": "flag_001",
      "actor": { "actorId": "353136425", "type": "USER", "name": "John Smith" },
      "comment": "Needs immediate attention",
      "createdAt": "2026-08-19T10:00:00Z"
    }
  ]
}

DELETE — Unflag an Instance

DELETE {{baseUrl}}/instances/:instanceId/flags/:actionId

Header Value
Authorization Bearer {{token}}
Content-Type application/json
Path Variable Required Description
actionId req The actionId from the flag entry, e.g. flag_001

Body · raw · JSON (optional)

{
  "comment": "Resolved"
}

Returns 400 (not 409) for error cases: no flag history, actionId mismatch, already unflagged.

Response 200 OK

{ "instanceId": "523440-42", "flags": [] }

Blocks

POST — Block an Instance

POST {{baseUrl}}/instances/:instanceId/blocks

Header Value
Authorization Bearer {{token}}
Content-Type application/json
accept */*
{
  "reason": "Waiting for design approval",
  "comment": "Blocked until design sign-off is received"
}

Both reason and comment are required. Returns 400 if either is absent or blank. Use GET /forms/:formId to discover valid blocking reasons for the form.

Response 200 OK

{
  "instanceId": "523440-42",
  "blocks": [
    {
      "actionId": "block_001",
      "reason": "Waiting for design approval",
      "comment": "Blocked until design sign-off is received",
      "actor": { "actorId": "353136425", "type": "USER", "name": "John Smith" }
    }
  ]
}

DELETE — Unblock an Instance

DELETE {{baseUrl}}/instances/:instanceId/blocks/:actionId

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "comment": "Design approved, unblocking"
}

comment is required — returns 400 if absent or blank.

Response 200 OK

{ "instanceId": "523440-42", "blocks": [] }

Votes

POST — Vote on an Instance

POST {{baseUrl}}/instances/:instanceId/votes

Header Value
Authorization Bearer {{token}}
accept application/json

No body required. Returns 409 if you have already voted on this instance.

Response 200 OK

{ "instanceId": "523440-42", "action": "voted", "votes": 1 }

DELETE — Remove Vote

DELETE {{baseUrl}}/instances/:instanceId/votes

Header Value
Authorization Bearer {{token}}

Returns 409 if you have not voted on this instance.

Response 200 OK

{ "instanceId": "523440-42", "action": "unvoted", "votes": 0 }

Links

Creates or removes a typed directional link between two instances. HIERARCHY links also set parentCard on the source instance.

PUT — Create a Link

PUT {{baseUrl}}/instances/:instanceId/link

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "to": {
    "workItemId": "ISS-50",
    "formId": "523440",
    "workSpaceId": "2110769"
  },
  "relationInverse": "fulfills",
  "metaType": "DEPENDENCY"
}

metaType values: HIERARCHY (default), DEPENDENCY, TRACEBAILITY, CONTAINMENT, ASSOCIATION.

Response 200 OK

{ "linkId": "lnk_001", "from": "ISS-42", "to": "ISS-50", "metaType": "DEPENDENCY" }

DELETE — Remove a Link

DELETE {{baseUrl}}/instances/:instanceId/link/:targetId?metaType=DEPENDENCY

Header Value
Authorization Bearer {{token}}
Query Param Required Description
metaType opt Must match the value used when the link was created. Defaults to HIERARCHY.

Response 200 OK

{ "linkId": "lnk_001", "removed": true }

Comments

Limitations: User mentions (@user), emoji, and inline attachments are not supported in comment text. Use POST /attachments to attach files to an instance.

POST — Add a Comment

POST {{baseUrl}}/instances/:instanceId/comments

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "content": "Reproduced on Chrome 126. Stack trace attached.",
  "type": "COMMENT"
}

content is required (min 1 char). type is optional, defaults to COMMENT.

Response 201 CREATED

{ "commentId": "cmt_abc123" }

GET — List Comments

GET {{baseUrl}}/instances/:instanceId/comments

Header Value
Authorization Bearer {{token}}
accept application/json

Response 200 OK

{
  "comments": [
    {
      "commentId": "cmt_abc123",
      "content": "Reproduced on Chrome 126.",
      "type": "COMMENT",
      "authorId": "353136425",
      "createdAt": "2026-08-19T10:05:00Z",
      "replies": []
    }
  ]
}

GET — Single Comment (with replies)

GET {{baseUrl}}/instances/:instanceId/comments/:commentId

Header Value
Authorization Bearer {{token}}
accept application/json

Response 200 OK

{
  "commentId": "cmt_abc123",
  "content": "Reproduced on Chrome 126.",
  "authorId": "353136425",
  "replies": [
    { "commentId": "cmt_def456", "content": "Also on Firefox.", "authorId": "353147453" }
  ]
}

PUT — Add a Reply

PUT {{baseUrl}}/instances/:instanceId/comments/:commentId/replies

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{ "content": "Also reproduced on Safari 17." }

Response 200 OK

{ "commentId": "cmt_ghi789" }

PUT — Edit Comment Text

PUT {{baseUrl}}/instances/:instanceId/comments/:commentId/content

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{ "content": "Reproduced on Chrome 126 and Edge 124. Stack trace attached." }

Response 200 OK

{ "commentId": "cmt_abc123", "updated": true }

DELETE — Delete Comment

DELETE {{baseUrl}}/instances/:instanceId/comments/:commentId

Header Value
Authorization Bearer {{token}}

Response 204 NO CONTENT — Empty body on success.

Attachments

POST — Upload a File

POST {{baseUrl}}/instances/:instanceId/attachments

Header Value
Authorization Bearer {{token}}
Content-Type Do NOT set manually — Postman sets this automatically for form-data

Body · form-data

Key Type Value
file File Select file from your computer (max 32 MB)

In Postman: Body tab → select form-data → set key to file → hover the key and change type from Text to File → click Select Files.

Response 201 CREATED

{ "attachmentId": "att_789012" }

POST — Link an External Resource

POST {{baseUrl}}/instances/:instanceId/attachments/link

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "attachmentName": "Design Mockup",
  "content": "https://figma.com/file/abc123",
  "linkedUsing": "Figma"
}

Response 201 CREATED

{ "attachmentId": "att_link_001" }

GET — List Attachments

GET {{baseUrl}}/instances/:instanceId/attachments

Header Value
Authorization Bearer {{token}}
accept application/json

Response 200 OK

{
  "attachments": [
    {
      "attachmentId": "att_789012",
      "name": "screenshot.png",
      "mimeType": "image/png",
      "fileSize": 204800,
      "createdAt": "2026-08-19T11:00:00Z"
    }
  ]
}

DELETE — Delete Attachment

DELETE {{baseUrl}}/instances/:instanceId/attachments/:attachmentId

Header Value
Authorization Bearer {{token}}

Response 204 NO CONTENT — Empty body on success.

Todos

GET — List Todos

GET {{baseUrl}}/instances/:instanceId/todos

Header Value
Authorization Bearer {{token}}
accept application/json
Param Required Description
assigneeId opt Filter by assignee user ID
limit opt Max results per page
pageToken opt Cursor for next page

Response 200 OK

{
  "todos": [
    {
      "todoId": "TODO1",
      "name": "Write unit tests",
      "status": "open",
      "assigneeId": "353136425",
      "estimate": 4
    }
  ]
}

POST — Create a Todo

POST {{baseUrl}}/instances/:instanceId/todos

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "name": "Write unit tests",
  "assigneeId": "353136425",
  "estimate": 4,
  "formId": "523440"
}

name is required. All other fields are optional.

Response 201 CREATED

{ "todoId": "TODO1" }

PATCH — Update a Todo

PATCH {{baseUrl}}/instances/:instanceId/todos/:todoId

Header Value
Authorization Bearer {{token}}
Content-Type application/json
{
  "estimate": 6
}

All fields optional: name, assigneeId, estimate. Only sent fields are updated.

Response 200 OK

{ "todoId": "TODO1", "estimate": 6 }

POST — Close a Todo

POST {{baseUrl}}/instances/:instanceId/todos/:todoId/close

Header Value
Authorization Bearer {{token}}

No body required.

Response 200 OK

{ "todoId": "TODO1", "status": "closed", "actualFinish": "2026-08-19T12:00:00Z" }

POST — Reopen a Todo

POST {{baseUrl}}/instances/:instanceId/todos/:todoId/reopen

Header Value
Authorization Bearer {{token}}

Response 200 OK

{ "todoId": "TODO1", "status": "open" }

DELETE — Delete a Todo

DELETE {{baseUrl}}/instances/:instanceId/todos/:todoId

Header Value
Authorization Bearer {{token}}

Response 200 OK

{ "message": "deleted" }

Time Entries

Time entries are keyed by todoId + date. Submitting the same pair again overwrites the existing entry. Date format: YYYY-MM-DD.

POST — Log Time

POST {{baseUrl}}/instances/:instanceId/todos/:todoId/timeentries/:date

Header Value
Authorization Bearer {{token}}
Content-Type application/json
Path Variable Required Description
date req Format YYYY-MM-DD, e.g. 2026-08-19. Cannot be a future date.
{
  "actual": 3.5,
  "remaining": 0.5
}

actual is required (hours logged). remaining and estimate are optional.

Response 201 CREATED

{
  "actual": 3.5,
  "remaining": 0.5,
  "latestRemaining": 0.5,
  "totalActual": 7.0,
  "timesheetDate": "2026-08-19"
}

GET — Get Time Entry for a Date

GET {{baseUrl}}/instances/:instanceId/todos/:todoId/timeentries/:date

Header Value
Authorization Bearer {{token}}
accept application/json

Response 200 OK

{
  "actual": 3.5,
  "remaining": 0.5,
  "timesheetDate": "2026-08-19"
}

Returns 404 if no entry exists for that todo + date combination.

GET — List Time Entries by Date Range

GET {{baseUrl}}/timeentries?timesheetStartDate=2026-08-01&timesheetEndDate=2026-08-19&limit=50

Header Value
Authorization Bearer {{token}}
accept application/json
Param Required Description
timesheetStartDate req YYYY-MM-DD
timesheetEndDate req YYYY-MM-DD
workspaceIds[] opt Repeatable — filter by workspace
limit opt 1–100, default 50
pageToken opt Cursor for next page

Response 200 OK

{
  "items": [
    {
      "todoId": "TODO1",
      "instanceId": "523440-42",
      "actual": 3.5,
      "timesheetDate": "2026-08-19"
    }
  ],
  "total": 1
}
  • Was this helpful?
  • Yes   No