Blue API — Reference

Base URL & auth

All endpoints are served by this app at https://<your-app>/api/blue/* and return JSON. They proxy Blue's GraphQL API using the org token stored server-side — so callers (GHL, scripts, n8n) send no Blue credentials; just call the URL with a JSON body.

Every response is shaped { success: boolean, ... }. On failure you get { success: false, message, error } with an HTTP 4xx/5xx. Writes accept an optional projectId (the SID id) to scope the request.

Server env (set in Vercel): BLUE_TOKEN_ID, BLUE_TOKEN_SECRET, BLUE_COMPANY_ID, BLUE_TEMPLATE_PROJECT_ID. Generated in Blue → Organisation Settings → API.

Using these in a GoHighLevel automation

In a GHL Workflow, add a Webhook action (or Custom Webhook):

  • Method: as listed per endpoint (POST to create, PATCH to update).
  • URL: https://<your-app>/api/blue/...
  • Headers: Content-Type: application/json (no auth header needed — the server holds the Blue token).
  • Body: JSON, mapping GHL custom values like {{ contact.study_id }}.

Example: when a study is approved, create a kickoff card and assign it

POST https://<your-app>/api/blue/todos
Content-Type: application/json

{
  "todoListId": "{{ custom_values.sid_up_next_list_id }}",
  "title": "Kickoff — {{ contact.study_name }}",
  "text": "Auto-created from GHL when the study was approved.",
  "projectId": "{{ custom_values.sid_project_id }}"
}

# → returns { "success": true, "card": { "id": "...", "title": "..." } }
# Feed card.id into a follow-up Webhook step to assign:

POST https://<your-app>/api/blue/todos/{{ card.id }}/assign
{ "user": "Josh Nichols", "projectId": "{{ custom_values.sid_project_id }}" }

Tip: a one-time GET /api/blue/lists?projectId=… gives you the column ids to store as GHL custom values.

GET/api/blue/projects
List all SIDs

Get every study workspace in the PVIP org (id + name + timestamps).

Full URL

GET https://<your-app>/api/blue/projects

Example response

{
  "success": true,
  "count": 156,
  "projects": [
    {
      "id": "cm6awe5ja00kk38pr0zb04up8",
      "uid": "b872eb79349344f88213e05ff6fae2db",
      "name": "SID313 Foot Ulcer Cari Clinical Trials",
      "description": "",
      "createdAt": "2025-01-06T16:26:57.652Z",
      "updatedAt": "2026-02-10T07:04:12.038Z"
    }
  ]
}
POST/api/blue/projects
Create a SID (clone the template)

Start a new study. Clones the 'new template' workspace (lists + cards) and renames it. Pass fromTemplate:false for an empty workspace.

Full URL

POST https://<your-app>/api/blue/projects

Request body

{
  "name": "SID365 ERG Psoriasis",
  "description": "optional",
  "fromTemplate": true
}

Example response

{
  "success": true,
  "project": {
    "id": "viypjx3a2c3da5ms85d9aafi",
    "uid": "9ea18ceb27944302a92badcb44fdec7a",
    "name": "SID365 ERG Psoriasis",
    "description": "",
    "createdAt": "2025-01-06T16:26:57.652Z",
    "updatedAt": "2025-06-10T08:54:10.985Z"
  }
}
GET/api/blue/projects/{id}
Get one SID (board: columns + cards)

Read a study's full board — every column with its nested cards and assignees.

Full URL

GET https://<your-app>/api/blue/projects/{id}

Example response

{
  "success": true,
  "project": {
    "id": "viypjx3a2c3da5ms85d9aafi",
    "name": "SID365 ERG Psoriasis",
    "todoLists": [
      {
        "id": "h3f5w66fevrjuc4nxn9ppmze",
        "title": "Up Next",
        "position": 49151.25,
        "todosCount": 5,
        "todos": [
          {
            "id": "ehz6jonp9i1yi2e2ab7cwrp7",
            "title": "🎨 Creatives Development",
            "text": "These are for all of the images...",
            "done": false,
            "duedAt": null,
            "users": []
          }
        ]
      }
    ]
  }
}
GET/api/blue/lists?projectId={id}
List columns in a SID

Get just the columns (Up Next / Pending / In Progress / Completed) and their card counts.

Full URL

GET https://<your-app>/api/blue/lists?projectId={id}

Example response

{
  "success": true,
  "count": 4,
  "lists": [
    { "id": "h3f5w66fevrjuc4nxn9ppmze", "title": "Up Next", "position": 49151.25, "todosCount": 5 },
    { "id": "vo9720gzurx9skax4lxwpr0i", "title": "Pending", "position": 57343.125, "todosCount": 11 },
    { "id": "il1tct7kv9u2zbicwpsjtt1s", "title": "In Progress", "position": 65535, "todosCount": 0 },
    { "id": "grjg3rdz5v7oioy5kbon8u0e", "title": "Completed", "position": 131070, "todosCount": 0 }
  ]
}
POST/api/blue/lists
Create a column

Add a new column to a SID. Omit position to append after the last one.

Full URL

POST https://<your-app>/api/blue/lists

Request body

{
  "projectId": "viypjx3a2c3da5ms85d9aafi",
  "title": "QA"
}

Example response

{
  "success": true,
  "list": { "id": "cmqrqwxv205msnu01vwb76ep4", "title": "QA", "position": 196605 }
}
GET/api/blue/todos?projectId={id}&todoListId={listId}
List cards

List cards in a SID (todoListId optional to filter to one column). Each card is tagged with its column.

Full URL

GET https://<your-app>/api/blue/todos?projectId={id}&todoListId={listId}

Example response

{
  "success": true,
  "count": 17,
  "cards": [
    {
      "id": "0073bea3371740bf92a9cf08d348e6f3",
      "title": "Build landing page",
      "text": "See patients.vip [https://patients.vip] for brand.",
      "done": false,
      "duedAt": null,
      "users": [],
      "todoList": { "id": "h3f5w66fevrjuc4nxn9ppmze", "title": "Up Next" }
    }
  ]
}
POST/api/blue/todos
Create a card

Add a task to a column. dueDate is ISO 8601. Pass projectId to scope the request.

Full URL

POST https://<your-app>/api/blue/todos

Request body

{
  "todoListId": "h3f5w66fevrjuc4nxn9ppmze",
  "title": "Build landing page",
  "text": "See https://patients.vip for brand.",
  "dueDate": "2026-07-01T00:00:00Z",
  "projectId": "viypjx3a2c3da5ms85d9aafi"
}

Example response

{
  "success": true,
  "card": {
    "id": "0073bea3371740bf92a9cf08d348e6f3",
    "uid": "a108d3b350d14e5ca7f02c097c284f0d",
    "title": "Build landing page"
  }
}
GET/api/blue/todos/{id}?projectId={id}
Get a card (full detail)

Read a card's content, extracted links, checklists, files and assignees.

Full URL

GET https://<your-app>/api/blue/todos/{id}?projectId={id}

Example response

{
  "success": true,
  "card": {
    "id": "0073bea3371740bf92a9cf08d348e6f3",
    "title": "Build landing page (v2)",
    "text": "See patients.vip [https://patients.vip] for brand.",
    "html": "See <a href=\"https://patients.vip\">patients.vip</a> for brand.",
    "done": false,
    "commentCount": 1,
    "todoList": { "id": "h3f5w66fevrjuc4nxn9ppmze", "title": "Up Next" },
    "users": [{ "id": "cm3exicja2kyrpo5om57ux2e9", "fullName": "Josh Nichols" }],
    "checklists": [],
    "links": [{ "url": "https://patients.vip", "label": "patients.vip" }]
  }
}
PATCH/api/blue/todos/{id}
Update a card

Change title/text/dueDate, mark done, or move to another column (set todoListId).

Full URL

PATCH https://<your-app>/api/blue/todos/{id}

Request body

{
  "title": "Build landing page (v2)",
  "done": true,
  "todoListId": "grjg3rdz5v7oioy5kbon8u0e",
  "projectId": "viypjx3a2c3da5ms85d9aafi"
}

Example response

{
  "success": true,
  "card": { "id": "0073bea3371740bf92a9cf08d348e6f3", "title": "Build landing page (v2)" }
}
POST/api/blue/todos/{id}/assign
Assign / unassign a member

Provide a Blue userId, or `user` as a name/email to resolve. action defaults to 'assign'.

Full URL

POST https://<your-app>/api/blue/todos/{id}/assign

Request body

{
  "user": "Josh Nichols",
  "action": "assign",
  "projectId": "viypjx3a2c3da5ms85d9aafi"
}

Example response

{
  "success": true,
  "action": "assign",
  "userId": "cm3exicja2kyrpo5om57ux2e9",
  "result": { "success": true }
}
GET/api/blue/todos/{id}/comments?projectId={id}
List a card's comments

Read the comment thread on a card.

Full URL

GET https://<your-app>/api/blue/todos/{id}/comments?projectId={id}

Example response

{
  "success": true,
  "totalCount": 1,
  "comments": [
    {
      "id": "cmqrqx13t05nmnu01tpgpfsnr",
      "text": "Kicking this off — see patients.vip [https://patients.vip]",
      "createdAt": "2026-06-24T07:22:28.698Z",
      "user": { "id": "cm3exicja2kyrpo5om57ux2e9", "fullName": "Josh Nichols" }
    }
  ]
}
POST/api/blue/todos/{id}/comments
Add a comment

Post a comment to a card.

Full URL

POST https://<your-app>/api/blue/todos/{id}/comments

Request body

{
  "text": "Kicking this off",
  "projectId": "viypjx3a2c3da5ms85d9aafi"
}

Example response

{
  "success": true,
  "comment": {
    "id": "cmqrqx13t05nmnu01tpgpfsnr",
    "text": "Kicking this off",
    "createdAt": "2026-06-24T07:22:28.698Z"
  }
}
GET/api/blue/users?q={search}
List org members

Find a userId by name/email before assigning a card. q is an optional filter.

Full URL

GET https://<your-app>/api/blue/users?q={search}

Example response

{
  "success": true,
  "count": 1,
  "users": [
    { "id": "cm3exicja2kyrpo5om57ux2e9", "fullName": "Josh Nichols", "email": "" }
  ]
}