PostoBox API

Welcome to the PostoBox API documentation. Use this API to integrate PostoBox with your applications and services.

The PostoBox API is a RESTful API that allows you to programmatically manage events, questions, and organization data. All requests and responses use JSON format.

Base URL

https://api.postobox.app/v1

Content Type

application/json

API Version

The current API version is v1. All endpoints are prefixed with /v1 on the API subdomain.

Authentication

All API requests require authentication using an API key.

Getting an API Key

To get an API key, you need to be an owner or admin of an organization. Navigate to Settings → API Keys in your dashboard.

  1. Go to your organization settings
  2. Click on "API Keys" in the Integrations section
  3. Click "Create Key" and select the required scopes
  4. Copy your API key - it will only be shown once

Using Your API Key

Include your API key in the Authorization header using the Bearer scheme:

Example Requestbash
curl -X GET "https://api.postobox.app/v1/events" \
  -H "Authorization: Bearer pk_live_xxxx_your_api_key_here"

Keep Your Key Secret

Your API key grants access to your organization's data. Never share it publicly or commit it to version control. Use environment variables in your applications.

Permission Scopes

API keys have granular permission scopes. Only request the scopes you need:

ScopeDescription
events:readList and view events
events:writeCreate, update, and delete events
questions:readList and view questions
questions:writeSubmit new questions
questions:moderateApprove, reject, and delete questions
organization:readView organization information

Rate Limiting

API requests are rate limited based on your organization's plan.

PlanRequests per Minute
Free60
Starter300
Professional1,000
Enterprise5,000

Rate limit information is included in the response headers:

HeaderDescription
X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRequests remaining in current window
X-RateLimit-ResetUnix timestamp when the limit resets
Retry-AfterSeconds until you can retry (only on 429 responses)

Error Handling

The API uses standard HTTP status codes and returns errors in a consistent format.

All error responses follow this format:

Error Response Formatjson
{
  "error": {
    "message": "Description of what went wrong",
    "status": 400,
    "code": "ERROR_CODE",
    "details": { ... }
  }
}

HTTP Status Codes

CodeDescription
200Success
201Created
204No Content (successful delete)
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found
409Conflict - Resource already exists
429Rate limit exceeded
500Internal server error

Events

Manage Q&A events for your organization.

GET/events

List all events for your organization.

Required Scope

events:read
Query Parameters
ParameterTypeDescription
pageintegerPage number for paginationDefault: 1
limitintegerItems per page (max 100)Default: 20
activebooleanFilter by active status

Example Request

curl -X GET "https://api.postobox.app/v1/events?page=1&limit=10" \
  -H "Authorization: Bearer pk_live_xxxx_your_key"

Example Response

{
  "data": [
    {
      "id": "clx123...",
      "title": "Tech Conference 2024",
      "slug": "tech-conference-2024",
      "description": "Annual tech conference",
      "startDate": "2024-06-01T09:00:00.000Z",
      "endDate": "2024-06-01T18:00:00.000Z",
      "active": true,
      "needModeration": true,
      "allowAnonymous": true,
      "questionCount": 42,
      "createdAt": "2024-05-01T10:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 5,
    "totalPages": 1
  }
}
POST/events

Create a new event.

Required Scope

events:write
Request Body
ParameterTypeDescription
title*stringEvent title (2-200 chars)
subtitlestringEvent subtitle (max 500 chars)
slug*stringURL-friendly identifier (lowercase, hyphens only)
descriptionstringEvent description (max 5000 chars)
startDate*ISO 8601Event start date/time
endDate*ISO 8601Event end date/time
needModerationbooleanRequire question moderationDefault: true
allowAnonymousbooleanAllow anonymous questionsDefault: true
maxQuestionLengthintegerMax question lengthDefault: 1200
activebooleanEvent is accepting questionsDefault: false

Example Request

curl -X POST "https://api.postobox.app/v1/events" \
  -H "Authorization: Bearer pk_live_xxxx_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Product Launch Q&A",
    "slug": "product-launch-qa",
    "description": "Ask questions about our new product",
    "startDate": "2024-07-15T14:00:00.000Z",
    "endDate": "2024-07-15T16:00:00.000Z",
    "needModeration": true,
    "active": false
  }'
GET/events/{eventId}

Get a specific event by ID.

Required Scope

events:read
Path Parameters
ParameterTypeDescription
eventId*stringThe event ID
PATCH/events/{eventId}

Update an existing event. Only include fields you want to change.

Required Scope

events:write

Example Request

curl -X PATCH "https://api.postobox.app/v1/events/clx123..." \
  -H "Authorization: Bearer pk_live_xxxx_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "active": true,
    "title": "Updated Event Title"
  }'
DELETE/events/{eventId}

Delete an event. This is a soft delete - the event can be recovered.

Required Scope

events:write
Deleting an event will also make all its questions inaccessible.

Questions

Manage questions within events.

GET/events/{eventId}/questions

List all questions for an event.

Required Scope

questions:read
Query Parameters
ParameterTypeDescription
pageintegerPage numberDefault: 1
limitintegerItems per page (max 100)Default: 20
statusstringFilter by status: DEFAULT, SELECTED, ANSWERED, REJECTED
sortBystringSort field: createdAt, voteCountDefault: createdAt
sortOrderstringSort order: asc, descDefault: desc

Example Response

{
  "data": [
    {
      "id": "clq123...",
      "text": "What's the roadmap for 2024?",
      "voteCount": 15,
      "status": "SELECTED",
      "isAnonymous": true,
      "authorUsername": null,
      "createdAt": "2024-06-01T10:30:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 42,
    "totalPages": 3
  }
}
POST/events/{eventId}/questions

Submit a new question to an event.

Required Scope

questions:write
Request Body
ParameterTypeDescription
text*stringQuestion text
identifierstringCustom identifier for the submitter
Questions are automatically set to DEFAULT status if the event requires moderation, or SELECTED if moderation is disabled.

Example Request

curl -X POST "https://api.postobox.app/v1/events/clx123.../questions" \
  -H "Authorization: Bearer pk_live_xxxx_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "What are the key features of the new release?",
    "identifier": "user-12345"
  }'
GET/events/{eventId}/questions/{questionId}

Get a specific question by ID.

Required Scope

questions:read
PATCH/events/{eventId}/questions/{questionId}

Update a question's status (moderation).

Required Scope

questions:moderate
Request Body
ParameterTypeDescription
status*stringNew status: DEFAULT, SELECTED, ANSWERED, or REJECTED

Question Statuses

StatusDescription
DEFAULTPending moderation
SELECTEDApproved, visible to audience
ANSWEREDQuestion has been answered
REJECTEDRejected, hidden from audience

Example Request

curl -X PATCH "https://api.postobox.app/v1/events/clx.../questions/clq..." \
  -H "Authorization: Bearer pk_live_xxxx_your_key" \
  -H "Content-Type: application/json" \
  -d '{ "status": "SELECTED" }'
DELETE/events/{eventId}/questions/{questionId}

Delete a question.

Required Scope

questions:moderate

Organization

Get information about your organization.

GET/organization

Get your organization's information including usage and limits.

Required Scope

organization:read

Example Response

{
  "data": {
    "id": "clo123...",
    "name": "Acme Corp",
    "subdomain": "acme",
    "slug": "acme-corp",
    "logo": "https://...",
    "primaryColor": "#BE123C",
    "plan": "PROFESSIONAL",
    "limits": {
      "maxEvents": 50,
      "maxQuestions": 5000
    },
    "usage": {
      "eventCount": 12,
      "questionCount": 847,
      "memberCount": 5
    },
    "isActive": true,
    "createdAt": "2024-01-15T10:00:00.000Z"
  }
}