Skip to main content

GQueues REST API Reference

Written by Jeff

Getting Started

Overview

The GQueues REST API lets you read queues and tasks, and create and update queues and sections, and create, update and delete tasks programmatically. It uses a single versioned endpoint with an action parameter to select the operation.

All requests and responses use JSON. The API follows REST conventions: GET for read operations and POST for write operations.

Base URL

All API requests are made to:

Authentication

Every request must include a valid API access token in the Authorization header using the Bearer scheme:

Authorization: Bearer gq_your_access_token_here

Access tokens are created from the API tab in your GQueues settings. Tokens are prefixed with gq_ and contain 256 bits of entropy.

❗️Please Note: Tokens are shown only once at creation time. Copy and securely store your token before closing the dialog. If a token is compromised, revoke it immediately from Settings.

Authentication Errors

Status

Meaning

401

Missing, malformed, expired, or revoked token.

403

Account is not permitted to use the API (e.g. a banned account), or the token lacks the scope required for the requested operation.

Rate Limits

The API enforces rate limits to ensure fair usage and system stability. Limits are applied at multiple levels:

  • Per IP address -- protects against burst and sustained abuse from a single source.

  • Per account -- overall request budget for your account.

  • Per token -- individual limit for each access token.

Paid subscriptions receive more generous limits than the Lite tier. Write operations like task creation have tighter limits than read operations.

Each account also has a 30-day request budget, shared by all of its tokens and connected MCP clients: 5,000 requests on GQueues for BUSINESS, 3,000 on GQueues for YOU, and 50 on GQueues Lite. The MCP tab in Settings shows it as credits, with the reset date. Once it is spent, every request returns 429 until the budget resets.

Rate Limit Response

When a limit is exceeded, the API returns 429 with a Retry-After header indicating how many seconds to wait before retrying.

HTTP/1.1 429 Too Many Requests
Retry-After: 62
Content-Type: application/json

{"error": "{"error": "You've reached the per-minute limit for creating tasks on your plan. Try again in 40 seconds."}"}

Best practice: Always respect the Retry-After header. Clients that retry immediately or in tight loops may be subject to longer backoff periods.

Idempotency

All POST (mutating) endpoints require an Idempotency-Key request header. This ensures that retrying a request (e.g. due to a network timeout) does not create duplicate resources.

Idempotency-Key: create-task-abc123

Key Rules

  • Required on all POST requests. Omitting it returns 400.

  • Max length: 128 characters

  • Allowed characters: a-z, A-Z, 0-9, _, -, .

  • Scoped per account and endpoint path: Different accounts can reuse the same key without conflict, and the same key used on different POST actions will not collide.

  • TTL: How long a cached response stays replayable depends on the action. Create operations (createTask, createSection, createQueue, createComment) cache for 24 hours -- a wide replay window. Update operations (updateTask, deleteTask, updateQueue, updateSection) cache for only 2 minutes -- long enough to absorb an immediate retry, short enough not to mask a later intentional re-edit. After the window expires, the same key can be reused for a new request.

  • Only successful responses are cached. Only 2xx responses are stored in the idempotency cache. If a request returns a 4xx or 5xx, the key is not cached and the same key may immediately be reused to retry the request.

Idempotency Behavior

Scenario

Result

First request with a new key

Processed normally. 2xx responses are cached for the action's TTL (24 hours for create actions, 2 minutes for update and delete actions). Non-2xx responses are not cached.

Retry with same key and same body

Cached response replayed. Idempotent-Replayed: true header included.

Same key but different body

422 -- key already used with a different payload.

Concurrent duplicate request

409 with Retry-After: 1 header. Retry after 1 second.

👉 Pro Tip: For automated integrations, generate deterministic keys by hashing the request content (e.g. SHA-256 of the task text). This prevents duplicates even across retries. Use a random UUID only when you intentionally want to create a duplicate.

Error Handling

The API returns errors as JSON objects with an error field and an appropriate HTTP status code.

{
"error": "Missing required parameter: queueKey"
}

Common Error Codes

Status

Meaning

400

Bad request -- missing or invalid parameters, malformed JSON, non-object body, unknown action, or Idempotency-Key validation failure (missing header, empty, exceeds 128 characters, or contains invalid characters)

401

Unauthorized -- missing, invalid, expired, or revoked token

403

Forbidden -- banned account, the token lacks the required scope, or insufficient queue/category/team permissions

409

Conflict -- a concurrent duplicate request (idempotency lock held), or a background cross-queue move that is still running (see Update Task). Both include a Retry-After header.

413

Payload Too Large -- request body exceeds 64 KB, or an Update Task request with move.queueKey is too large to run in the background

415

Unsupported Media Type -- Content-Type must be application/json for POST requests

422

Unprocessable Entity -- idempotency key reused with a different request body. If the earlier request was a background move, it may still be applied; check the task before retrying.

429

Too Many Requests -- rate limit exceeded (see Retry-After header)

500

Internal server error


Endpoints

The API exposes the following actions on the single /v1 endpoint:

Action

Method

Purpose

getQueues

GET

List queues grouped by category.

getCategories

GET

List personal categories.

getTeams

GET

List the teams the account belongs to.

getCurrentUser

GET

Return the signed-in user's email and time zone.

listTasks

GET

List a queue's active or archived tasks.

searchTasks

GET

Full-text search tasks across all queues.

createTask

POST

Create one or more tasks.

updateTask

POST

Update one or more existing tasks.

deleteTask

POST

Move one or more tasks to the trash.

createSection

POST

Add a section to a queue.

createQueue

POST

Create a personal or team queue.

getSections

GET

List a queue's sections.

updateQueue

POST

Rename a queue, or edit its notes or color.

updateSection

POST

Rename a section, or edit its notes or color.

getComments

GET

List a task's comments, newest first.

createComment

POST

Add a comment to a task.


Get Queues

Returns queues accessible to the authenticated user, grouped by category.

Please Note: This only includes queues where tasks actually live (My Queues, Team Queues, Inbox). Any view that is filtering tasks in your account (Smart Queues and Save Searches) are not included.

GET /v1?action=getQueues

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be getQueues

scope

string

No

Comma-separated list of queue categories to return. Valid values: personal, team, shared. Defaults to all three if omitted or if no valid values are provided.

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Example Request

curl -X GET "https://api.gqueues.com/v1?action=getQueues&scope=personal,team" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

Returns a JSON object with keys for each requested scope. Each key maps to an array of queue objects.

{
{
"personal": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Inbox",
"notes": "",
"numOpen": 12,
"numCompleted": 45,
"isInbox": true,
"isPage": false,
"color": "gq-queue-bkgnd-1",
"dateCreated": "2024-01-15T10:30:00",
"lastModified": "2024-03-20T14:00:00",
"permission": { "view": true, "update": true, "manage": true, "publish": true },
"editable": { "name": false, "notes": false, "color": true, "sections": true }
},
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Follow-ups",
"notes": "",
"numOpen": 5,
"numCompleted": 18,
"isInbox": false,
"isPage": false,
"color": "gq-queue-bkgnd-7",
"dateCreated": "2024-02-10T08:00:00",
"lastModified": "2024-03-19T16:45:00",
"categoryName": "Work",
"categoryKey": "ahNzfmdxdWV1ZXMtaHJk...",
"permission": { "view": true, "update": true, "manage": true, "publish": true },
"editable": { "name": true, "notes": true, "color": true, "sections": true }
}
],
"team": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Sprint Backlog",
"notes": "Current sprint items",
"numOpen": 8,
"numCompleted": 23,
"isInbox": false,
"isPage": false,
"color": "gq-queue-bkgnd-12",
"isTeamInbox": false,
"dateCreated": "2024-02-01T09:00:00",
"lastModified": "2024-03-18T11:00:00",
"teamName": "Engineering",
"teamKey": "ahNzfmdxdWV1ZXMtaHJk...",
"permission": { "view": true, "update": true, "manage": true, "publish": false },
"editable": { "name": true, "notes": true, "color": true, "sections": true }
}
]
}

Queue Object Fields

Field

Type

Description

key

string

Unique identifier for the queue. Use this value as the queueKey parameter in other endpoints.

name

string

Display name of the queue.

notes

string

Queue description or notes, as plain text. Empty string if none.

numOpen

integer

Number of active (non-completed) tasks.

numCompleted

integer

Number of completed tasks.

isInbox

boolean

true if this is the user's personal Inbox queue.

isPage

boolean

true if this queue backs a Page. Its name and color belong to the page and cannot be changed through Update Queue; its notes, sections and tasks can.

color

string or null

The queue color, as a CSS class such as gq-queue-bkgnd-3. null if none is set.

isTeamInbox

boolean

Team queues only. true if this is the team's Inbox queue.

teamName

string

Team queues only. Name of the team this queue belongs to.

teamKey

string

Team queues only. Datastore key of the team this queue belongs to.

categoryName

string

Personal queues in a category only. Name of the category. Personal queues with the same name can appear in different categories -- use this field to disambiguate. Omitted for the Inbox and for personal queues that are not in a category.

categoryKey

string

Personal queues in a category only. Datastore key of the category, emitted alongside categoryName.

dateCreated

string or null

ISO 8601 datetime when the queue was created. null if not set.

lastModified

string or null

ISO 8601 datetime when the queue was last modified. null if not set.

permission

object

Permissions the authenticated user has on this queue (see below).

editable

object

Which of this queue's fields this account may actually change (see below).

Permission Object

Field

Type

Description

view

boolean

Can view the queue and its tasks.

update

boolean

Can add, edit, and complete tasks.

manage

boolean

Can rename, reorder, and delete the queue.

publish

boolean

Can share or publish the queue.

Editable Object

Combines this account's rights with the queue's own restrictions, so a client can predict a refusal instead of discovering it. permission says what the account may do; editable says what it may do to this queue.

Field

Type

Description

name

boolean

Whether Update Queue will accept a rename. false on the personal Inbox and on a page-backing queue, and without manage rights.

notes

boolean

Whether Update Queue will accept a notes edit. false on the personal Inbox, and without update rights.

color

boolean

Whether Update Queue will accept a color change. false on a page-backing queue, and without manage rights.

sections

boolean

Whether Create Section and Update Section will accept a change in this queue. Requires update rights. A section already being deleted still refuses, so check isBeingDeleted on the section too.


Get Categories

Returns the account's personal categories (including empty ones), in the account's configured display order. Categories are the top-level groupings that hold personal queues; use a category key as the categoryKey parameter in Create Queue.

GET /v1?action=getCategories

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be getCategories

Example Request

curl -X GET "https://api.gqueues.com/v1?action=getCategories" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

{
"categories": [
{ "key": "ahNzfmdxdWV1ZXMtaHJk...", "name": "Work", "order": 0, "numQueues": 4 },
{ "key": "ahNzfmdxdWV1ZXMtaHJk...", "name": "Personal", "order": 1, "numQueues": 2 }
]
}

Category Object Fields

Field

Type

Description

key

string

The category's datastore key.

name

string

The category name.

order

integer

The category's position in the account's ordering (0-based).

numQueues

integer

Number of queues in the category.


Get Teams

Returns the teams the account belongs to (including teams with zero queues), in the account's configured order. Returns an empty list when the account is not permitted to use teams. Use a team key as the teamKey parameter in Create Queue.

GET /v1?action=getTeams

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be getTeams

Example Request

curl -X GET "https://api.gqueues.com/v1?action=getTeams" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

{
"teams": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Engineering",
"access": "manager",
"numQueues": 7,
"canCreateQueues": true
}
]
}

Team Object Fields

Field

Type

Description

key

string

The team's datastore key.

name

string

The team name.

access

string

The account's access level on this team: one of owner, manager, collaborator, completer, commenter.

numQueues

integer

Number of queues in the team.

canCreateQueues

boolean

Whether the account may create queues in this team (true for owner/manager). Mirrors the rule enforced by Create Queue.


Get Current User

Returns the authenticated user's email address and IANA time zone. Use the email when a request means "me" (for example, assigning a task to yourself), and the time zone when turning a local time into the UTC value Snooze expects.

GET /v1?action=getCurrentUser

Example Request

curl -X GET "https://api.gqueues.com/v1?action=getCurrentUser" \   -H "Authorization: Bearer gq_your_access_token_here"

Response

{   "email": "you@example.com",   "tz": "America/New_York" }

Get Sections

Returns a queue's sections, in the order they appear in the queue.

GET /v1?action=getSections

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be getSections

queueKey

string

Yes

Datastore key of the queue whose sections to list. Maximum 500 characters. The account must be authorized to view it.

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Example Request

curl "https://api.gqueues.com/v1?action=getSections&queueKey=ahNzfmdxdWV1ZXMtaHJk..." \
-H "Authorization: Bearer gq_your_access_token_here"

Response

{
"sections": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"sectionId": "sec-1a2b3c",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "This Week",
"color": "gq-queue-bkgnd-8",
"notes": "Time-sensitive items",
"position": "00000000",
"isBeingDeleted": false,
"collapsedByDefault": false
}
]
}

Section Object Fields

Field

Type

Description

key

string

The section's datastore key. Use this value as the sectionKey parameter in Update Section and Create Task.

sectionId

string

The section's stable client-side identifier.

queueKey

string

Datastore key of the queue the section belongs to.

name

string

The section name, as plain text.

color

string or null

The section color (CSS class), or null if none is set.

notes

string or null

The section notes, as plain text.

position

string

The section's ordering position within the queue.

isBeingDeleted

boolean

true while the section is in the process of being deleted. A section in this state cannot be updated.

collapsedByDefault

boolean

Whether the section renders collapsed on first view.

Please Note: Sections being deleted are returned rather than filtered out, so a client can tell the difference between a section that is going away and one that never existed. Unlike the sections array in List Tasks, this response contains only real sections -- there is no synthetic "(No Section)" bucket.

Please Note: When the queue does not exist or the account is not authorized to view it, the response is 403 with a masked error message (the same message for not-found and not-authorized, so callers cannot probe which keys exist).


List Tasks

Returns the tasks in a single queue with pagination support. By default it returns the queue's active tasks grouped into sections; pass filter=archived to return the queue's archived (completed) tasks instead.

Please Note: This action was previously named getActiveTasks. The old name is no longer supported.

GET /v1?action=listTasks

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be listTasks

queueKey

string

Yes

Datastore key of the queue to list. The account must be authorized to view it. A key that does not resolve and a key naming a queue the account cannot view both return the same masked 403, so callers cannot probe which keys exist.

filter

string

No

Which task states to return. Defaults to active. Valid forms: active (optionally combined as active,snoozed to also include snoozed tasks), or archived used alone to return the queue's archived (completed) tasks. active must be present unless the filter is exactly archived; archived cannot be combined with active/snoozed. Any other value returns 400.

limit

integer

No

Maximum number of top-level tasks per page. Default: 200; must be between 1 and 200. A non-numeric value falls back to the default; out-of-range numeric values return 400.

cursor

string

No

Pagination offset (a non-negative integer, as returned in a prior response's nextCursor). Defaults to 0. Non-numeric or negative values return 400.

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Example Request

curl -X GET "https://api.gqueues.com/v1?action=listTasks&queueKey=ahNzfm...&filter=active,snoozed&limit=50" \
-H "Authorization: Bearer gq_your_access_token_here""

To list the queue's archived tasks instead:

curl -X GET "https://api.gqueues.com/v1?action=listTasks&queueKey=ahNzfm...&filter=archived&limit=50" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

Returns a paginated list of tasks. For the active/snoozed filter, the response also includes section information; the sections array is omitted when filter=archived.

{
"items": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"title": "Draft the quarterly report",
"notes": "Include revenue and churn.",
"completed": false,
"crossed": false,
"tags": ["reports", "q3"],
"position": "00000000_0001",
"queueName": "Work",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"numComments": 0,
"hasSubitems": false,
"attachments": [],
"access": "user",
"addComments": true,
"assignments": [],
"link": "https://app.gqueues.com/main/task/active/5629499534213120-6207617754725632",
"sectionKey": "ahNzfmdxdWV1ZXMtaHJk...",
"dueDate": {
"dueDate": "Fri, August 15",
"duration": null,
"rawDate": "2025-08-15",
"title": "Fri, August 15 @ 9:00 AM",
"text": "Aug 15 @ 9:00 AM",
"repeats": false
},
"schedule": {
"dueDate": { "local": "2025-08-15T09:00:00", "tz": "America/New_York" },
"dueTime": true
},
"creationDate": { "utc": "2025-08-01T14:22:05Z", "tz": "America/New_York" },
"lastModified": { "utc": "2025-08-02T09:11:40Z", "tz": "America/New_York" },
"subitems": []
}
],
"sections": [
{
"key": "ahNzfmdxdWV...",
"sectionId": "sec-1",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "In Progress",
"color": "gq-queue-bkgnd-8",
"notes": "",
"position": "00000000",
"isBeingDeleted": false,
"items": ["ahNzfmdxdWV1ZXMtaHJk..."]
},
{
"key": "",
"name": "(No Section)",
"color": "gq-queue-bkgnd-1",
"notes": "",
"position": "",
"items": []
}
],
"topLevelCount": 12,
"nextCursor": "50",
"limit": 50
}

Response Fields

Field

Type

Description

items

array

The page of top-level task objects (see Task Object Fields below).

sections

array

The queue's sections (see Section Object Fields below). Each section's items array is filtered to only the task keys present on the current page. Omitted entirely when filter=archived.

topLevelCount

integer

Total number of top-level tasks in the queue (before pagination).

nextCursor

string or null

Cursor to pass as cursor to fetch the next page, or null when there are no more pages.

limit

integer

The effective limit used after validation.

Task Object Fields

This is the canonical task shape returned by List Tasks and Search Tasks. (Create Task and Update Task return a slightly smaller subset -- see those endpoints.)

Field

Type

Description

key

string

The task's datastore key.

title

string

The task title (HTML when the task is rich-text enabled).

notes

string

The task notes; empty string when none.

completed

boolean

Whether the task is archived. false for every task in the default active list; true for every task returned with filter=archived.

crossed

boolean

Whether the task is crossed off (strikethrough, still active).

tags

array

The task's tags, sorted case-insensitively.

position

string

The task's raw ordering position within its container; empty string when unset.

queueName

string

Name of the task's queue.

queueKey

string

Datastore key of the task's queue.

numComments

integer

Number of comments on the task.

hasSubitems

boolean

Whether the task has sub-tasks.

attachments

array

The task's attachments. Empty array if none.

access

string

The requester's access level for this task.

addComments

boolean

Whether the requester may add comments on this task.

assignments

array

Assignees (see Assignment Object Fields below); empty when unassigned.

link

string

Deep link that opens the task in the GQueues web app. Note the host is app.gqueues.com, not the API host. Present on every task object, including nested subitems; the entries in parents do not carry it.

sectionKey

string

Datastore key of the task's section. Present only on a top-level task that is in a section (and that has no task ancestry — see parents).

parentKey

string

Datastore key of the parent task. Present only on nested sub-tasks returned inline within a parent's subitems.

parents

array

Ancestry breadcrumb for a sub-task surfaced at the top level rather than inline — as happens with filter=archived and Search Tasks results. An ordered list of {type, key, name} entries: a leading {"type": "section", ...} when the task sits in a section, followed by each ancestor task from the root down to the immediate parent. Emitted in place of sectionKey/parentKey for such items.

dueDate

object

Human-readable due-date display bundle (see Due Date Object Fields below). Present only when the task has a due date.

schedule

object

Round-trippable schedule (see Schedule Object Fields below). Present only when the task has a due date. Pass this shape back to Update Task.

snoozeInfo

object

Snooze details (see Snooze Info Object Fields below). Present only when the task is snoozed.

creationDate

object

{utc, tz} timestamp the task was created. Present when set.

lastModified

object

{utc, tz} timestamp the task was last modified. Present when set.

completionDate

object

{utc, tz} timestamp the task was archived. Present when set.

subitems

array

Nested sub-tasks, same shape as a task object; empty array when none.

Datetime values: creationDate, lastModified, completionDate, and snoozeInfo.until are {utc, tz} objects -- utc is an unambiguous Z-suffixed ISO-8601 instant; tz is the account's IANA timezone id. schedule.dueDate is a {local, tz} object -- local is the offset-less wall-clock string (date-only when the task has no time-of-day).

Assignment Object Fields

Field

Type

Description

key

string

The assignment's datastore key.

email

string

Assignee's email address.

name

string

Assignee's profile name.

profile

string

Assignee's profile picture URL; may be empty.

comment

string

Assignment comment.

completed

boolean

Whether the assignee has completed the assignment.

commentAllowed

boolean

Whether the requester may comment on this assignment.

dateCompleted

object or null

{utc, tz} timestamp the assignment was completed, or null.

Due Date Object Fields

Field

Type

Description

dueDate

string

Long human-readable date, e.g. Fri, August 15.

rawDate

string

The due date as YYYY-MM-DD.

duration

integer or null

Event duration in minutes, or null.

title

string

Long human-readable date, with time appended when the task has a due time.

text

string

Short human-readable date (year shown only when not the current year), with time when applicable.

repeats

string or false

The recurrence summary string when the task repeats, otherwise false.

reminder

object

{type, amount}. Present only when the task has a reminder and calendar integration is on.

Schedule Object Fields

Field

Type

Description

dueDate

object

{local, tz} wall-clock due date/time (date-only string when the task has no due time).

dueTime

boolean

Whether the task has a specific time of day.

reminder

object

{type, amount} where type is email or alert and amount is minutes before due. Present only when set.

duration

integer

Duration in minutes. Present only when set.

recurrence

object

Recurrence rule (freqPattern, freqNum, repeatFrom, and optionally repeatOn, repeatBy, endDate). Present only when the task repeats.

Snooze Info Object Fields

Field

Type

Description

until

object

{utc, tz} timestamp the task is snoozed until.

comment

string or null

Unsnooze comment, or null.

Section Object Fields

Field

Type

Description

key

string

Section datastore key. Empty string ("") for the synthetic "(No Section)" bucket (see note below).

sectionId

string

Stable section identifier used internally (distinct from key, which is a Datastore key). Omitted on the "(No Section)" bucket.

queueKey

string

Datastore key of the queue the section belongs to. Omitted on the "(No Section)" bucket.

name

string

Section name, as plain text.

color

string

CSS class for section color (e.g. gq-queue-bkgnd-8). For the "(No Section)" bucket this is the queue's default color class.

notes

string or null

Section notes, as plain text.

position

string

Sort position key.

isBeingDeleted

boolean

true while the section is in the process of being deleted. Omitted on the "(No Section)" bucket.

items

array

Task keys belonging to this section that appear on the current page.

The "(No Section)" bucket: Every active-list response includes one synthetic section, with key: "" and name: "(No Section)", that collects the queue's top-level tasks not assigned to any named section. It carries only key, name, color, notes, position, and items — sectionId, queueKey, and isBeingDeleted are omitted. Sort sections by position to place it correctly relative to the named sections.

Pagination

To iterate through all tasks in a queue:

  1. Make an initial request (optionally with a limit).

  2. Read nextCursor from the response.

  3. If nextCursor is not null, make another request with cursor set to that value.

  4. Repeat until nextCursor is null.

❗️Please Note: Pagination applies to top-level tasks only. Subtasks are always returned inline within their parent's subitems array.


Search Tasks

Searches tasks across all of the account's queues via full-text search. Results use the same task shape as List Tasks (each task carries its own queueName/queueKey), so they round-trip into Update Task.

GET /v1?action=searchTasks

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be searchTasks

query

string

Yes

The search query. Supports query-string syntax plus date macros such as [today] and [+N days]. Must be non-empty.

filter

string

No

Which task states to include. Comma-separated; allowed tokens: active, snoozed, archived (e.g. snoozed,archived). Defaults to active. Any other value returns 400.

limit

integer

No

Maximum results per page, between 1 and 25. When omitted, the server uses its default (25).

cursor

string

No

Opaque pagination cursor returned in a prior response's nextCursor. Must match the format the server issued, or 400 is returned.

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Example Request

curl -X GET "https://api.gqueues.com/v1?action=searchTasks&query=report&filter=active,archived&limit=25" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

{
"items": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"title": "Draft the quarterly report",
"notes": "",
"completed": false,
"crossed": false,
"tags": ["q3"],
"position": "00000000_0001",
"queueName": "Work",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"numComments": 0,
"hasSubitems": false,
"attachments": [],
"access": "user",
"addComments": true,
"assignments": [],
"link": "https://app.gqueues.com/main/task/active/5629499534213120-6207617754725632",
"subitems": []
}
],
"nextCursor": "25_PARTITION_1.7_PARTITION_ahNzfmdxdWV1ZXMtaHJk...",
"limit": 25
}

Response Fields

Field

Type

Description

items

array

Matching task objects. Same shape as the List Tasks Task Object. Each item carries its own queueName/queueKey.

nextCursor

string or null

Opaque cursor to pass as cursor for the next page, or null when there are no more results.

limit

integer

The effective limit used for this page.

Please Note: Search returns 503 when search is temporarily unavailable for the account, and 403 when search is not available for the account.


Create Task

Creates one or more tasks in the authenticated user's account.

Each instruction can be submitted in one of two modes:

  • Structured mode (default): You supply text (the subject), and optionally any of the structured fields below (queueKey, notes, dueDate, tags, assignments, etc.). No quick-add parsing is performed, but text and notes accept basic HTML formatting (bold, italics, links, lists), which is sanitized before it is stored.

  • Quick-add mode: Set parseQuickAddSyntax: true to have the server extract due date, tags, queue, assignments, and notes out of the text using quick-add syntax. A [Queue Name] in the text that does not match an existing queue creates one. Structured fields (queueKey, notes, dueDate, etc.) still apply in this mode and are merged with what the text says. If both set the same attribute to different values, the instruction fails with a conflict error rather than picking one.

POST /v1

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Content-Type

Yes

Must be application/json

Idempotency-Key

Yes

Unique key for duplicate prevention. See Idempotency.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be createTask

instructions

array

Yes

Array of instruction objects (see below). Must be a non-empty list with at most 25 entries. The entire request body must not exceed 64 KB.

Instruction Object

Field

Type

Required

Description

text

string

Yes

Task subject. Maximum 1,500 characters. Accepts basic HTML formatting, which is sanitized on save. In quick-add mode, this string also encodes due date, tags, queue, assignments, and notes.

parseQuickAddSyntax

boolean

No

If true, parse quick-add syntax out of text. Defaults to false. When true, the structured fields below are merged with the parsed values; a conflict between the two fails the instruction.

queueKey

string

No

Datastore key of the target queue. Obtain from Get Queues. Maximum 500 characters. If omitted, the task is added to the account's Inbox.

notes

string

No

Notes body. Maximum 1,500 characters. Accepts basic HTML formatting, which is sanitized on save.

dueDate

string

No

Due date in YYYY-MM-DD format.

dueTime

string

No

Time of day in HH:MM (24-hour) format. Requires dueDate.

reminderType

string

No

Reminder channel: email or alert. Requires dueDate.

reminderAmount

integer

No

Minutes before due to send the reminder (max 40320). Requires reminderType.

duration

integer

No

Event duration in minutes (positive; max 527040 — one year).

tags

array

No

List of tag strings (each max 1,500 bytes).

assignments

array

No

List of assignee email strings (max 50; each max 254 chars).

sectionKey

string

No

Datastore key of a section within the target queue. Mutually exclusive with parentKey.

parentKey

string

No

Datastore key of a parent task (creates a sub-task). Mutually exclusive with sectionKey.

prevItemKey

string

No

Key of the task to position this new task after. When omitted, the task goes to the top or bottom of its container according to the account's "insert new tasks at top" setting. A key from before a cross-queue move still resolves.

Example Request -- structured mode

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-task-a1b2c3d4" \
-d '{
"action": "createTask",
"instructions": [
{
"text": "Review API docs",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"notes": "Check the new instruction fields",
"dueDate": "2025-08-15",
"tags": ["documentation"]
}
]
}'

Example Request -- quick-add mode

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-task-e5f6g7h8" \
-d '{
"action": "createTask",
"instructions": [
{ "text": "Review API docs tomorrow #documentation [Product] :: Check the new fields", "parseQuickAddSyntax": true },
{ "text": "Send weekly report Friday at 5pm", "parseQuickAddSyntax": true }
]
}'

Response

Returns a results array with one entry per instruction, in the same order as the input.

{
"results": [
{
"status": "created",
"task": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"title": "Review API docs",
"notes": "Check the new instruction fields",
"completed": false,
"crossed": false,
"link": "https://app.gqueues.com/main/task/active/5629499534213120-4785074604081152",
"tags": ["documentation"],
"assignments": [],
"queueName": "Product",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"position": "00000000_0001",
"creationDate": { "utc": "2025-08-01T14:22:05Z", "tz": "America/New_York" },
"dueDate": {
"dueDate": "Fri, August 15",
"duration": null,
"rawDate": "2025-08-15",
"title": "Fri, August 15",
"text": "Aug 15",
"repeats": false
},
"schedule": {
"dueDate": { "local": "2025-08-15T00:00:00", "tz": "America/New_York" },
"dueTime": false
}
}
}
]
}

Result Object Fields

Field

Type

Description

status

string

"created" on success, "error" on failure.

task

object

The created task (see below). Present only on success.

error

string

Error message. Present only on failure.

Created Task Object

The created task uses the same field conventions as the List Tasks Task Object, with these differences: it is serialized directly (so it omits the numComments, hasSubitems, attachments, access, addComments, and subitems fields that List Tasks adds), and it always includes queueName/queueKey. Its assignments entries omit commentAllowed. Present fields: key, title, notes, completed, crossed, link, tags, assignments, queueName, queueKey, position, and -- when applicable -- sectionKey, parentKey, creationDate, lastModified, completionDate, dueDate, schedule, and snoozeInfo. See the List Tasks Task Object for each field's meaning.

Request-Level Errors

These apply to the overall request and cause the entire call to fail with a 400 before any instruction is processed:

  • Idempotency-Key header is required -- header is missing.

  • Idempotency-Key header must not be empty -- header is present but blank.

  • Idempotency-Key exceeds maximum length of 128 -- header exceeds the 128-character limit.

  • Idempotency-Key contains invalid characters (allowed: a-z, A-Z, 0-9, _, -, .) -- header has disallowed characters.

  • Instructions must be a list -- instructions is not a JSON array.

  • Instructions list must not be empty -- instructions is an empty array.

  • Too many instructions (max 25) -- instructions exceeds 25 entries.

Per-Instruction Error Handling

Each instruction is processed independently. If one instruction fails, the others still succeed. Possible per-instruction errors include: missing/empty text, text over 1,500 characters, invalid queueKey/sectionKey/parentKey, invalid date/reminder/duration values, an unresolvable or unauthorized queue, or an internal error.


Update Task

Updates one or more existing tasks. Each instruction targets a task by taskKey and applies exactly one editable facet (properties, tags, assignments, schedule, move, status, or snooze). To change more than one facet on a task, send it as separate instructions.

POST /v1

Request Headers

Same as Create Task -- requires Authorization, Content-Type: application/json, and an Idempotency-Key header.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be updateTask

instructions

array

Yes

1 to 25 instruction objects (see below). Must be non-empty.

Instruction Object

Each instruction must include taskKey and exactly one of the facet fields below.

Field

Type

Required

Description

taskKey

string

Yes

Datastore key of the task to update.

title

string

--

New task title. Non-empty (a title cannot be cleared); max 1,500 characters. May be combined with notes -- together they form the single "properties" facet.

notes

string

--

New task notes; max 1,500 characters. Combined with title as the properties facet.

tags

array

--

Full desired tag set (replace-semantics). On a team task, creating a tag the team does not have yet needs update rights, so an assignee can apply existing team tags but not add new ones. A team with locked tags rejects new tags for everyone.

assignments

array

--

Full desired set of assignee emails (replace-semantics). Max 50; each max 254 chars. An assignee who cannot otherwise edit the task may only remove themselves: send the current list without their own email.

schedule

object or null

--

Full desired date state (replace-semantics). See Schedule facet below. Send null to clear the schedule.

move

object

--

Re-position the task within its current queue. See Move facet below.

status

string

--

One of archive, unarchive, crossOff, uncross. Assignees can only archive or unarchive; the change applies to their own assignment.

snooze

object or null

--

Snooze the task. See Snooze facet below. Send null to clear the snooze.

Clearing a facet: schedule and snooze are the only facets whose presence counts even when the value is null -- send JSON null to clear them. For the other facets, a null value is treated as "field not supplied."

Schedule facet -- object with:

Field

Type

Required

Description

dueDate

object

Yes

{local, tz} wall-clock date/time, e.g. {"local": "2025-08-15T09:00:00"}. Required when schedule is present.

dueTime

boolean

No

Whether dueDate includes a specific time. Defaults to false.

reminder

object

No

{type, amount} where type is email or alert and amount is minutes before due (max 40320).

duration

integer

No

Duration in minutes (positive; max 527040 — one year).

recurrence

object

No

{freqPattern, freqNum?, repeatOn?, repeatBy?, repeatFrom?, endDate?}. freqPattern is one of Daily, Weekly, Monthly, Annually. freqNum is 1-100 (default 1). repeatOn (weekday names) applies to Weekly. repeatBy (byWeek/byMonth) applies to Monthly. repeatFrom is due (default) or completed. endDate is a {local, tz} value on or after the due date.

Move facet -- object with:

Field

Type

Required

Description

to

string

Yes

One of queue (top level), section, parent (nest under a task), or current (reorder in place).

sectionKey

string

--

Target section key. Required when to is section; not allowed otherwise.

parentKey

string

--

Target parent task key. Required when to is parent; not allowed otherwise.

prevItemKey

string

No

Key of the task to position this task after within the destination. Omit to place first.

Note: Without queueKey, any sectionKey, parentKey or prevItemKey must name a container in the task's current queue. A cross-queue move always lands at the top level of the destination queue; to place the task in a section or under a parent there, send a second updateTask instruction with to set to section or parent, using the returned key. A queueKey naming the task's current queue behaves like to = queue without it: the task is placed first at the top level, so repeating a cross-queue move puts the task first in that queue. A key in move other than to, queueKey, sectionKey, parentKey and prevItemKey is rejected by name. The task must be active or crossed (not archived, snoozed, or trashed) to be moved, and the caller needs update rights on the destination queue.

Cross-queue moves run in the background. A request containing any move.queueKey instruction runs as a background job. The API waits a few seconds for it to finish. If it is still running, the response is 409 with a Retry-After header and a jobId. Wait, then repeat the identical request (same body, same Idempotency-Key) to collect the result -- the move is not applied twice. A request too large to queue returns 413; send the move.queueKey instruction in its own request. If another request moves or deletes the task while the move runs, that instruction fails with an error saying so.

Moving to another account or team re-keys the task. When the destination queue belongs to a different account or team, the task and every subtask get new keys. The result entry then includes keyMap, and task.key is the new key. Old keys keep resolving for updateTask, deleteTask, and createTask's parentKey and prevItemKey, but use the new keys from then on.

Snooze facet -- object with:

Field

Type

Required

Description

until

object

Yes

{utc, tz} timestamp to snooze until (at least two minutes in the future).

comment

string

No

Optional unsnooze comment.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: update-task-a1b2c3d4" \
-d '{
"action": "updateTask",
"instructions": [
{ "taskKey": "ahNzfmdxdWV1ZXMtaHJk...", "title": "Draft the Q3 report" },
{ "taskKey": "ahNzfmdxdWV1ZXMtaHJk...", "schedule": { "dueDate": { "local": "2025-08-15T09:00:00" }, "dueTime": true } },
{ "taskKey": "ahNzfmdxdWV1ZXMtaHJk...", "snooze": null }
]
}'

Response

Returns a results array with one entry per instruction, in the same order as the input.

{
"results": [
{
"status": "updated",
"task": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"title": "Draft the Q3 report",
"notes": "",
"completed": false,
"crossed": false,
"link": "https://app.gqueues.com/main/task/active/5629499534213120-6207617754725632",
"tags": [],
"assignments": [],
"queueName": "Work",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"position": "00000000_0001"
}
},
{
"status": "error",
"error": "Not authorized to update this task"
}
]
}

Result Object Fields

Field

Type

Description

status

string

"updated" on success, "error" on failure.

task

object

The updated task. Present only on success. Same serialized shape as the Create Task Created Task Object (a subset of the List Tasks Task Object).

visible

boolean

Present as false, alongside taskKey and without task, when the update succeeded but the task is no longer visible to the caller (for example, after removing yourself from it).

keyMap

object

Present only when a move re-keyed the task. Maps each old key -- the task's and every subtask's -- to its new key.

cascaded

array

Present only when a schedule change in a Gantt queue moved dependent tasks: one {key, startDate, dueDate} entry per moved task.

error

string

Error message. Present only on failure.

Please Note: Envelope-level problems (missing/empty instructions, a non-list instructions, or more than 25 instructions) fail the whole request with a 400 and no results array. Per-instruction failures (validation, not-found, not-authorized) are reported individually within results.


Delete Task

Moves one or more tasks to the trash. Deletion is recoverable -- tasks are trashed for 30 days before being permanently removed.

POST /v1

Request Headers

Same as Create Task -- requires Authorization, Content-Type: application/json, and an Idempotency-Key header.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be deleteTask

instructions

array

Yes

1 to 25 instruction objects (see below). Must be non-empty.

Instruction Object

Field

Type

Required

Description

taskKey

string

Yes

Datastore key of the task to trash.

instanceOnly

boolean

No

For a recurring task: true trashes only the current occurrence; false (default) trashes the whole series.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: delete-task-a1b2c3d4" \
-d '{
"action": "deleteTask",
"instructions": [
{ "taskKey": "ahNzfmdxdWV1ZXMtaHJk..." },
{ "taskKey": "ahNzfmdxdWV1ZXMtaHJk...", "instanceOnly": true }
]
}'

Response

{
"results": [
{ "status": "deleted", "taskKey": "ahNzfmdxdWV1ZXMtaHJk..." },
{ "status": "error", "error": "Not authorized to delete this task" }
]
}

Result Object Fields

Field

Type

Description

status

string

"deleted" on success, "error" on failure.

taskKey

string

Key of the trashed task. Present only on success.

error

string

Error message. Present only on failure.

Please Note: As with Update Task, envelope-level problems (missing/empty/oversized instructions) fail the whole request with a 400; per-instruction failures are reported individually within results.


Create Section

Creates a new section at the end of a queue.

POST /v1

Request Headers

Same as Create Task -- requires Authorization, Content-Type: application/json, and an Idempotency-Key header.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be createSection

queueKey

string

Yes

Datastore key of the queue to add the section to. Maximum 500 characters.

name

string

Yes

Section name, as plain text. Must be non-blank, and at most 250 characters once stored.

notes

string

No

Optional section notes, as plain text, at most 1000 characters once stored.

Please Note: Length is counted on the stored form, which HTML-escaping lengthens. A line break inside either value is stored as a space, and leading and trailing whitespace is trimmed -- so a value read back may be a normalized form of what was sent. See Update Section for the same rules.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-section-a1b2c3d4" \
-d '{
"action": "createSection",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "This Week",
"notes": "Time-sensitive items"
}'

Response

{
"section": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"sectionId": "sec-1a2b3c",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "This Week",
"color": "gq-queue-bkgnd-8",
"notes": "Time-sensitive items",
"position": "00000000",
"isBeingDeleted": false,
"collapsedByDefault": false
}
}

Section Object Fields

Field

Type

Description

key

string

The section's datastore key.

sectionId

string

The section's stable client-side identifier.

queueKey

string

Datastore key of the queue the section belongs to.

name

string

The section name.

color

string

The section color (CSS class).

notes

string or null

The section notes.

position

string

The section's ordering position within the queue.

isBeingDeleted

boolean

Whether the section is currently being deleted.

collapsedByDefault

boolean

Whether the section renders collapsed on first view.

Please Note: Validation errors return 400 (e.g. missing/empty queueKey or name, or non-string notes). When the queue does not exist or the account cannot view it, the response is 403 with a masked error message (the same message for not-found and not-viewable, so callers cannot probe which keys exist). When the queue is viewable but the account lacks update rights on it, the 403 says so explicitly.


Create Queue

Creates a new personal or team queue. Exactly one of categoryKey (personal queue) or teamKey (team queue) must be supplied -- there is no default container.

POST /v1

Request Headers

Same as Create Task -- requires Authorization, Content-Type: application/json, and an Idempotency-Key header.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be createQueue

name

string

Yes

Queue name. Non-empty; trimmed. Maximum 50 characters.

notes

string

No

Optional queue notes. Maximum 1,500 characters.

categoryKey

string

Conditional

Target personal category key (from Get Categories). Supply exactly one of categoryKey or teamKey.

teamKey

string

Conditional

Target team key (from Get Teams). Supply exactly one of categoryKey or teamKey.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-queue-a1b2c3d4" \
-d '{
"action": "createQueue",
"name": "Roadmap",
"notes": "Q3 planning",
"categoryKey": "ahNzfmdxdWV1ZXMtaHJk..."
}'

Response

Returns a queue object with the same fields as the Get Queues Queue Object.

{
"queue": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Roadmap",
"notes": "Q3 planning",
"numOpen": 0,
"numCompleted": 0,
"isInbox": false,
"isPage": false,
"color": "gq-queue-bkgnd-19",
"dateCreated": "2025-08-01T14:22:05",
"lastModified": "2025-08-01T14:22:05",
"permission": { "view": true, "update": true, "manage": true, "publish": true },
"editable": { "name": true, "notes": true, "color": true, "sections": true },
"categoryName": "Work",
"categoryKey": "ahNzfmdxdWV1ZXMtaHJk..."
}
}

For a team queue, the response includes isTeamInbox, teamName, and teamKey instead of the category fields, and permission reflects the account's team role.

Please Note: notes is plain text in both directions -- send it as you want it read, and it comes back the same way. A line break in name is stored as a space. Use Update Queue to change any of these afterwards.

Please Note: Validation errors return 400 -- e.g. a missing/empty or too-long name, non-string or too-long notes, or supplying neither or both of categoryKey/teamKey ("Exactly one of categoryKey or teamKey is required"). When the target category or team does not exist, is deleted, or the account is not authorized to create a queue in it, the response is 403 with a single masked error message (so callers cannot probe which keys exist).


Update Queue

Renames a queue, edits its notes, or changes its color. Any combination of the three may be sent in one request; at least one is required.

POST /v1

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Content-Type

Yes

application/json

Idempotency-Key

Yes

Unique key for this request (see Idempotency).

Request Body

Field

Type

Required

Description

action

string

Yes

Must be updateQueue

queueKey

string

Yes

Datastore key of the queue to update. Maximum 500 characters.

name

string

No

New queue name. Must be non-blank and at most 50 characters -- but both rules apply only to an actual rename, so sending back the name you read is always accepted (see the note below). Requires manage rights.

notes

string

No

New notes, as plain text, at most 1500 characters. Empty string clears them. Requires update rights.

color

string

No

New color, as one of the queue color classes gq-queue-bkgnd-1 through gq-queue-bkgnd-32. A queue's color cannot be cleared. Requires manage rights.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: update-queue-a1b2c3d4" \
-d '{
"action": "updateQueue",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Client Work",
"notes": "Q3 planning"
}'

Response

Returns the updated queue object, with the same fields as the Get Queues Queue Object.

{
"queue": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "Client Work",
"notes": "Q3 planning",
"numOpen": 4,
"numCompleted": 0,
"isInbox": false,
"isPage": false,
"color": "gq-queue-bkgnd-3",
"dateCreated": "2025-08-01T14:22:05",
"lastModified": "2025-08-04T09:10:11",
"permission": { "view": true, "update": true, "manage": true, "publish": true },
"editable": { "name": true, "notes": true, "color": true, "sections": true },
"categoryName": "Work",
"categoryKey": "ahNzfmdxdWV1ZXMtaHJk..."
}
}

Per-Field Permissions

Rights are checked per field, matching the web app. A request naming several fields is refused as a whole if the account lacks the rights for any one of them, and nothing is written.

Field

Right required

name

manage

color

manage

notes

update

Read the editable object on the queue (see Queue Object Fields) to know which fields this account may change on this queue before attempting a write.

Sending a name back unchanged is not a rename. A name equal to the queue's current name -- compared after the same whitespace normalization applied on write -- writes nothing and is never refused, on any queue, for any reason. That includes the length and non-blank rules, so a queue whose stored name is longer than 50 characters (names written through other clients are not bounded) can be read and posted back without a 400. Only an actual change is validated and permission-checked.

Please Note: Some queues refuse some fields regardless of rights. The personal Inbox refuses name and notes. A page-backing queue (isPage: true) refuses name and color, because both belong to the page rather than the queue -- its notes, sections and tasks remain editable. Each refusal returns 403 with an explicit message naming the reason, not a masked "not found".

Please Note: Validation errors return 400 -- e.g. a missing or over-long queueKey, a non-string name or notes, notes over 1500 characters, a color outside the vocabulary, or naming none of name/notes/color. When the section does not exist, or its queue does not exist or is not viewable by the account, the response is 403 with a masked error message. Lacking update rights on a viewable queue returns 403 with an explicit message.


Update Section

Renames a section, edits its notes, or changes its color. Any combination of the three may be sent in one request; at least one is required.

POST /v1

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Content-Type

Yes

application/json

Idempotency-Key

Yes

Unique key for this request (see Idempotency).

Request Body

Field

Type

Required

Description

action

string

Yes

Must be updateSection

sectionKey

string

Yes

Datastore key of the section to update. Maximum 500 characters. The queue is derived from the section, so no queueKey is taken.

name

string

No

New section name, as plain text. Must be non-blank, and at most 250 characters once stored (see the note on length below).

notes

string

No

New section notes, as plain text, at most 1000 characters once stored. Empty string clears them.

color

string

No

New color, as one of the queue color classes gq-queue-bkgnd-1 through gq-queue-bkgnd-32. Empty string clears it.

Editing a section requires update rights on its queue -- the same right needed to add one. Read editable.sections on the queue (see Queue Object Fields) to know whether this account may edit sections there.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: update-section-a1b2c3d4" \
-d '{
"action": "updateSection",
"sectionKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "This Week",
"notes": "Time-sensitive items"
}'

Response

Returns the updated section object, with the same fields as the Get Sections Section Object.

{
"section": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"sectionId": "sec-1a2b3c",
"queueKey": "ahNzfmdxdWV1ZXMtaHJk...",
"name": "This Week",
"color": "gq-queue-bkgnd-8",
"notes": "Time-sensitive items",
"position": "00000000",
"isBeingDeleted": false,
"collapsedByDefault": false
}
}

Length is counted on the stored form. Section names and notes are stored HTML-escaped, and escaping lengthens the value -- & becomes &amp;, and a URL in notes is stored wrapped in an anchor tag. A value that is comfortably under the limit as you send it can exceed it once stored, so a rejection message says which limit was passed and that it counts the stored form.

Please Note: A line break inside a name or notes is stored as a space; both are single-line values. Leading and trailing whitespace is trimmed. So a value read back may be a normalized form of what was sent, and posting that value back is then a no-op.

Please Note: A section that is being deleted (isBeingDeleted: true) cannot be updated and returns 403 with an explicit message. Validation errors return 400 -- e.g. a missing or over-long sectionKey, a blank name, a value past its length limit, a color outside the vocabulary, or naming none of name/notes/color. When the section does not exist, or its queue does not exist or is not viewable by the account, the response is 403 with a masked error message.


Get Comments

Returns a task's comments, newest first.

GET /v1?action=getComments

Query Parameters

Parameter

Type

Required

Description

action

string

Yes

Must be getComments

taskKey

string

Yes

Datastore key of the task whose comments to list. Maximum 500 characters. The account must be authorized to view the task. A key from before a cross-queue move still resolves.

limit

integer

No

Comments per page, 1 to 100. Defaults to 20. Out-of-range values return 400.

cursor

string

No

Opaque pagination cursor returned in a prior response's nextCursor. Must be a cursor the server issued for this task, or 400 is returned.

Request Headers

Header

Required

Description

Authorization

Yes

Bearer <access_token>

Example Request

curl "https://api.gqueues.com/v1?action=getComments&taskKey=ahNzfmdxdWV1ZXMtaHJk...&limit=20" \
-H "Authorization: Bearer gq_your_access_token_here"

Response

{
"comments": [
{
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"taskKey": "ahNzfmdxdWV1ZXMtaHJk...",
"content": "Looks good, @sam@example.com can you review?",
"author": {
"email": "tao@example.com",
"name": "Tao Zhang",
"picUrl": "https://...",
"isCurrentUser": true
},
"dateCreated": { "utc": "2026-10-23T15:04:05Z", "tz": "America/Chicago" },
"edited": false
}
],
"nextCursor": null,
"limit": 20
}

Response Fields

Field

Type

Description

comments

array

Comment objects, newest first (see Comment Object Fields below).

nextCursor

string or null

Cursor to pass as cursor to fetch the next page, or null when there are no more pages. A full last page is followed by one empty page with nextCursor: null.

limit

integer

The effective limit used after validation.

Comment Object Fields

Field

Type

Description

key

string

The comment's datastore key. Changes if the task is later moved to another owner's queue.

taskKey

string

Datastore key of the task the comment is on.

content

string

The comment text, as plain text. Mentions appear as literal @email@domain and @all tokens.

author

object

email, name and picUrl of the author, plus isCurrentUser, which is true when the author is the authenticated account. When the author's account no longer exists: { "email": "", "name": "Former member", "picUrl": "", "isCurrentUser": false }.

dateCreated

object

utc (ISO-8601, Z-suffixed) and tz (the account's IANA time zone).

edited

boolean

Whether the comment has been edited since it was posted.

Please Note: A missing taskKey or an invalid limit or cursor returns 400. When the task does not exist or the account cannot view it, the response is 403 with a masked error message (the same message for not-found and not-viewable, so callers cannot probe which keys exist). A task in a team queue returns 403 when the account's plan no longer includes team features, unless the account is an assignee.


Create Comment

Adds a comment to a task.

POST /v1

Request Headers

Same as Create Task -- requires Authorization, Content-Type: application/json, and an Idempotency-Key header.

Request Body

Field

Type

Required

Description

action

string

Yes

Must be createComment

taskKey

string

Yes

Datastore key of the task to comment on. Maximum 500 characters. A key from before a cross-queue move still resolves.

content

string

Yes

The comment, as plain text. Leading and trailing whitespace is trimmed; must be non-blank and at most 2000 characters after trimming.

Mentions: write @ before the email of someone who has access to the task (for example @sam@example.com) to notify them. @all notifies everyone who can see the task. Notifications will send as long as the recipient hasn't disabled them. An email without access to the task is left as plain text and notifies no one.

Example Request

curl -X POST "https://api.gqueues.com/v1" \
-H "Authorization: Bearer gq_your_access_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: create-comment-a1b2c3d4" \
-d '{
"action": "createComment",
"taskKey": "ahNzfmdxdWV1ZXMtaHJk...",
"content": "Looks good, @sam@example.com can you review?"
}'

Response

Returns the new comment object, with the same fields as the Get Comments Comment Object, and the task's numComments after the add, so a client can update a task it already holds without another listTasks call.

{
"comment": {
"key": "ahNzfmdxdWV1ZXMtaHJk...",
"taskKey": "ahNzfmdxdWV1ZXMtaHJk...",
"content": "Looks good, @sam@example.com can you review?",
"author": {
"email": "tao@example.com",
"name": "Tao Zhang",
"picUrl": "https://...",
"isCurrentUser": true
},
"dateCreated": { "utc": "2026-10-23T15:04:05Z", "tz": "America/Chicago" },
"edited": false
},
"numComments": 4
}

Please Note: Validation errors return 400 (missing or empty taskKey, blank or non-string content, or content over 2000 characters). A task in the trash returns 400; restore it first. Archived tasks accept comments. When the task does not exist or the account cannot view it, the response is 403 with a masked error message. When the task is viewable but the account may not comment on it, the 403 says so, and adds that comments are not included in the plan when that is the reason. A task in a team queue returns 403 when the account's plan no longer includes team features, unless the account is an assignee. Posting the same content to the same task twice within 24 hours with the same Idempotency-Key replays the first response; use a new key to post a genuine repeat.

Did this answer your question?