Skip to content

API Overview

The Justack API is a RESTful API that allows you to create sessions, send messages, and manage recipients programmatically.

Base URL

https://api.justack.dev/v1

Authentication

All API requests require authentication using an API key in the Authorization header:

Terminal window
curl https://api.justack.dev/v1/sessions \
-H "Authorization: Bearer jstk_xxxxxxxxxxxxx"

API keys are available in the Dashboard. Keys use the jstk_ prefix.

Request Format

  • All requests must include Content-Type: application/json
  • Request bodies must be valid JSON
  • Timestamps use ISO 8601 format
Terminal window
curl https://api.justack.dev/v1/sessions \
-H "Authorization: Bearer jstk_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name": "My Session", "recipients": ["user@example.com"]}'

Response Format

Success Response (Single Resource)

{
"session_id": "01HXYZ...",
"name": "My Session",
"retention_months": 1,
"created_at": "2024-01-15T10:00:00Z",
"expires_at": "2024-02-14T10:00:00Z"
}

List Response (Cursor-Based Pagination)

{
"data": [
{ "session_id": "01HXYZ...", "name": "Session 1" },
{ "session_id": "01HABC...", "name": "Session 2" }
],
"next_cursor": "01HABC..."
}

When next_cursor is null, there are no more results.

Error Response

{
"error": {
"code": "BAD_REQUEST",
"message": "name is required"
}
}

Error Codes

HTTP StatusCodeDescription
400BAD_REQUESTMalformed request or invalid params
401UNAUTHORIZEDMissing or invalid API key
402PAYMENT_REQUIREDUsage limit reached for your tier
403FORBIDDENAPI key lacks required permissions
404NOT_FOUNDResource doesn’t exist
429RATE_LIMITEDToo many requests
500(varies)Server error

Usage Limits

Limits are based on your account tier:

ResourceFreePro
Recipients10100
Sessions25250
Messages / month10,000100,000
Invites / month50500
API keys320
Max retention1 month12 months

Check your current usage via the /v1/usage endpoint.

Endpoints

Sessions

MethodEndpointDescription
POST/v1/sessionsCreate a session
GET/v1/sessionsList sessions
GET/v1/sessions/:idGet session details
DELETE/v1/sessions/:idDelete a session

Messages

MethodEndpointDescription
POST/v1/sessions/:id/messagesSend a message
GET/v1/sessions/:id/messagesList messages

Recipients

MethodEndpointDescription
POST/v1/recipientsCreate a recipient
GET/v1/recipientsList recipients
GET/v1/recipients/:idGet recipient details
DELETE/v1/recipients/:idDelete a recipient
POST/v1/recipients/:id/inviteSend invite email
POST/v1/recipients/:id/invite-urlGet invite URL

WebSocket

MethodEndpointDescription
GET/v1/sessions/:id/wsSession WebSocket (API key or recipient token)
GET/v1/inbox/wsInbox WebSocket (recipient token)

Usage

MethodEndpointDescription
GET/v1/usageGet current usage and limits

Other

MethodEndpointDescription
GET/healthHealth check
POST/v1/auth/magic-linkRequest magic link (public)

Pagination

List endpoints use cursor-based pagination:

Terminal window
# First page
curl "https://api.justack.dev/v1/sessions?limit=20"
# Next page (use next_cursor from previous response)
curl "https://api.justack.dev/v1/sessions?limit=20&after=01HXYZ..."
ParameterTypeDefaultMaxDescription
limitnumber20100Number of items to return
afterstring--Cursor from previous next_cursor

Endpoint Details

Create Session

Terminal window
POST /v1/sessions

Request Body:

FieldTypeRequiredDescription
namestringYesDisplay name (1-255 chars)
retention_monthsnumberNoRetention period, 1-12 (default: 1)
recipientsarrayNoRecipient strings or objects
notifybooleanNoSend email notifications (default: false)
callback_urlstringNoWebhook callback URL

Recipients can be:

  • A string: email address, external ID, or recipient ID
  • An object: { "email": "..." } or { "external_id": "..." }

Response (201):

{
"session_id": "01HXYZ...",
"name": "My Session",
"retention_months": 1,
"created_at": "2024-01-15T10:00:00.000Z",
"expires_at": "2024-02-14T10:00:00.000Z",
"recipients": [
{
"recipient_id": "01HABC...",
"name": "user@example.com",
"email": "user@example.com",
"external_id": null,
"created_at": "2024-01-15T10:00:00.000Z"
}
]
}

Create Recipient

Terminal window
POST /v1/recipients

Request Body:

FieldTypeRequiredDescription
namestringYesDisplay name (1-255 chars)
emailstringNo*Email address
external_idstringNo*External identifier (max 255 chars)

*At least one of email or external_id is required.

Response (201):

{
"recipient_id": "01HABC...",
"name": "John Doe",
"email": "john@example.com",
"external_id": null,
"created_at": "2024-01-15T10:00:00.000Z"
}

Send Message

Terminal window
POST /v1/sessions/:sessionId/messages

Request Body:

FieldTypeRequiredDescription
rolestringYes"agent" or "recipient"
typestringYes"log" or "ask"
contentstringYesMessage content (1 byte - 1MB)
inputsstringNoJSON-encoded input definitions (for ask)
persistbooleanNoWhether to persist the message (default: true)

Response (201):

{
"id": "01HDEF...",
"role": "agent",
"type": "ask",
"content": "Deploy to production?",
"inputs": "[{\"type\":\"confirm\",\"name\":\"approved\"}]",
"response_content": null,
"responded_at": null,
"responded_by": null,
"persist": true,
"created_at": "2024-01-15T10:00:00.000Z"
}

Get Usage

Terminal window
GET /v1/usage

Response:

{
"tier": "free",
"usage": {
"recipients": { "current": 3, "limit": 10 },
"sessions": { "current": 5, "limit": 25 },
"messages": { "current": 150, "limit": 10000, "resets_at": "2024-02-01T00:00:00.000Z" },
"invites": { "current": 2, "limit": 50, "resets_at": "2024-02-01T00:00:00.000Z" }
}
}

Next Steps