Workspace

Who am I

GET/api/v1/whoami

GET /whoami
curl -X GET 'https://www.unitpost.com/api/v1/whoami' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0'
Response · 200
{
  "object": "whoami",
  "workspace": {
    "id": "id_123",
    "name": "Example",
    "slug": "string"
  },
  "credential": {
    "type": "api_key",
    "id": "id_123",
    "name": "Example",
    "prefix": "string",
    "scope": "full",
    "created_at": "2026-01-01T00:00:00.000Z",
    "last_used_at": "2026-01-01T00:00:00.000Z",
    "client_id": "client_123",
    "client_name": "string",
    "user": "string"
  },
  "capabilities": [
    "string"
  ],
  "rate_limit": {
    "limit": 1,
    "window_seconds": 0
  }
}

The calling credential: its workspace, the API key (name, prefix, scope preset) or the OAuth sign-in (the app and the member it acts for), the capabilities it may use after every clamp, and the workspace's rate limit. Call it first to plan within what the credential may do instead of learning by 403. Never returns the secret. Requires no capability: any valid credential may call it.

Response · 200 fields5 fields
FieldTypeDescription
objectrequiredstring—
workspacerequiredobject—
credentialrequiredobjectNever the secret.
capabilitiesrequiredstring[]What this credential may do, after every clamp: a call that needs another one answers 403 `insufficient_scope`.
rate_limitrequiredobject—
200401404422

List activity

GET/api/v1/activity

GET /activity
curl -X GET 'https://www.unitpost.com/api/v1/activity' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0'
Response · 200
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "activity",
      "id": "id_123",
      "type": "string",
      "subject": "contact",
      "subject_id": "subject_123",
      "subject_label": "string",
      "contact_id": "contact_123",
      "campaign_id": "campaign_123",
      "actor": {
        "name": "Example",
        "via": {
          "surface": "api",
          "credential": "api_key",
          "api_key_id": "api_key_123"
        }
      },
      "metadata": {},
      "created_at": "2026-01-01T00:00:00.000Z"
    }
  ]
}

The workspace activity log, newest first and cursor-paginated: what changed, when, and who changed it (actor.name: a teammate, System, Ask Unit) and, for a change made over the API, MCP or Ask Unit, how (actor.via, with the API key). The rows the dashboard's Activity page and each record's timeline show. Narrow with subject (and subject_id), contact_id, campaign_id, q (the record's name or the actor) and channel=email. Needs activity:read, which no key preset includes: the log names your teammates. Requires the activity:read capability.

Parameters9 fields
FieldTypeDescription
limitinteger · queryMax rows to return (default 20, max 100).
afterstring · queryReturn rows after this id (forward paging).
beforestring · queryReturn rows before this id (backward paging).
subjectstring · queryOnly changes to this kind of record.
subject_idstring · queryWith `subject`: one record's changes (its id, e.g. `dom_…`).
contact_idstring · queryOne contact's timeline (`con_…`).
campaign_idstring · queryA campaign's changes and what it led to (e.g. unsubscribes through it) (`cmp_…`).
qstring · queryPart of the record's name or the actor's (case-insensitive). At most 200 characters.
channelstring · query`email`: without SMS rows.
Response · 200 fields11 fields
FieldTypeDescription
objectrequiredstring—
idrequiredstring—
typerequiredstringWhat happened, e.g. `contact_created`, `campaign_sent`, `domain_verified`.
subjectrequiredenumcontact | segment | topic | field | template | component | campaign | email | domain | sender_email | library_image | api_key | webhook | suppression | message | handle | workspaceThe kind of record it happened to.
subject_idrequiredstring | nullThe record's id (prefixed where the record has a public id).
subject_labelrequiredstring | nullThe record's name at the time: a contact's email, a segment's name, …; a phone number is masked (`+1••••••7755`).
contact_idrequiredstring | null—
campaign_idrequiredstring | nullThe campaign the change is attributed to (e.g. an unsubscribe through its link).
actorrequiredobject—
metadatarequiredobjectDetail for the change, varying by `type`: a segment's or topic's name, a status before and after, a renamed field's keys, related ids (`campaign_id`, …). Descriptive keys only: addresses, URLs and error text stay in the dashboard.
created_atrequiredstring—
200401403422503

Rename the workspace

PATCH/api/v1/workspace

PATCH /workspace
curl -X PATCH 'https://www.unitpost.com/api/v1/workspace' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0' \
  -H 'Content-Type: application/json' \
  -d '{ }'
Response · 200
{
  "object": "workspace",
  "id": "id_123",
  "name": "Example",
  "slug": "string",
  "image_url": "https://example.com"
}

Change the workspace's name. Deleting the workspace stays in the dashboard. Requires the branding:write capability.

Request body1 field
FieldTypeDescription
namerequiredstringThe workspace's new name.
Response · 200 fields5 fields
FieldTypeDescription
objectrequiredstring—
idrequiredstring—
namerequiredstring—
slugrequiredstring—
image_urlrequiredstring | nullThe workspace image (its avatar in the dashboard).
200400401403422

Set the workspace image

PUT/api/v1/workspace/image

PUT /workspace/image
curl -X PUT 'https://www.unitpost.com/api/v1/workspace/image' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0' \
  -H 'Content-Type: application/json' \
  -d '{ }'
Response · 200
{
  "object": "workspace",
  "id": "id_123",
  "name": "Example",
  "slug": "string",
  "image_url": "https://example.com"
}

Replace the workspace image (its avatar in the dashboard, and the email logo when there's no brand logo), from a public https url or base64 data (PNG, JPEG, GIF or WebP, up to 5 MB and 16,384 px a side). Requires the branding:write capability.

Request body4 fields
FieldTypeDescription
urlstringA public https image to fetch (no redirects, no private addresses). PNG, JPEG, GIF or WebP, up to 5 MB and 16,384 px a side (50 megapixels at most); anything else is a 422 naming `url`.
datastringThe image bytes, base64 (no `data:` prefix). Base64 adds a third, and a request over ~6 MB is refused before it arrives, so this fits about 4 MB of image; send larger images (up to 5 MB) by `url`. At most 16,384 px a side and 50 megapixels; anything else is a 422 naming `data`.
content_typeenumimage/png | image/jpeg | image/gif | image/webpRequired with `data`; refused with `url` (the server sends the type).
filenamestringShown in the library. Defaults to the URL's file name, or `image`.
Response · 200 fields5 fields
FieldTypeDescription
objectrequiredstring—
idrequiredstring—
namerequiredstring—
slugrequiredstring—
image_urlrequiredstring | nullThe workspace image (its avatar in the dashboard).
200400401403422429502503

Remove the workspace image

DELETE/api/v1/workspace/image

DELETE /workspace/image
curl -X DELETE 'https://www.unitpost.com/api/v1/workspace/image' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0'
Response · 200
{
  "object": "workspace",
  "id": "id_123",
  "name": "Example",
  "slug": "string",
  "image_url": "https://example.com"
}

Clear the workspace image. Requires the branding:write capability.

Response · 200 fields5 fields
FieldTypeDescription
objectrequiredstring—
idrequiredstring—
namerequiredstring—
slugrequiredstring—
image_urlrequiredstring | nullThe workspace image (its avatar in the dashboard).
200401403

Search docs and guides

Search the docs and product guides.