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/v1Content Type
application/jsonAPI Version
/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.
- Go to your organization settings
- Click on "API Keys" in the Integrations section
- Click "Create Key" and select the required scopes
- 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:
curl -X GET "https://api.postobox.app/v1/events" \
-H "Authorization: Bearer pk_live_xxxx_your_api_key_here"Keep Your Key Secret
Permission Scopes
API keys have granular permission scopes. Only request the scopes you need:
| Scope | Description |
|---|---|
events:read | List and view events |
events:write | Create, update, and delete events |
questions:read | List and view questions |
questions:write | Submit new questions |
questions:moderate | Approve, reject, and delete questions |
organization:read | View organization information |
Rate Limiting
API requests are rate limited based on your organization's plan.
| Plan | Requests per Minute |
|---|---|
| Free | 60 |
| Starter | 300 |
| Professional | 1,000 |
| Enterprise | 5,000 |
Rate limit information is included in the response headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per minute |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the limit resets |
Retry-After | Seconds 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": {
"message": "Description of what went wrong",
"status": 400,
"code": "ERROR_CODE",
"details": { ... }
}
}HTTP Status Codes
| Code | Description |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 400 | Bad Request - Invalid parameters |
| 401 | Unauthorized - Invalid or missing API key |
| 403 | Forbidden - Insufficient permissions |
| 404 | Not Found |
| 409 | Conflict - Resource already exists |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
Events
Manage Q&A events for your organization.
/eventsList all events for your organization.
Required Scope
events:readQuery Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number for paginationDefault: 1 |
limit | integer | Items per page (max 100)Default: 20 |
active | boolean | Filter 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
}
}/eventsCreate a new event.
Required Scope
events:writeRequest Body
| Parameter | Type | Description |
|---|---|---|
title* | string | Event title (2-200 chars) |
subtitle | string | Event subtitle (max 500 chars) |
slug* | string | URL-friendly identifier (lowercase, hyphens only) |
description | string | Event description (max 5000 chars) |
startDate* | ISO 8601 | Event start date/time |
endDate* | ISO 8601 | Event end date/time |
needModeration | boolean | Require question moderationDefault: true |
allowAnonymous | boolean | Allow anonymous questionsDefault: true |
maxQuestionLength | integer | Max question lengthDefault: 1200 |
active | boolean | Event 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
}'/events/{eventId}Get a specific event by ID.
Required Scope
events:readPath Parameters
| Parameter | Type | Description |
|---|---|---|
eventId* | string | The event ID |
/events/{eventId}Update an existing event. Only include fields you want to change.
Required Scope
events:writeExample 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"
}'/events/{eventId}Delete an event. This is a soft delete - the event can be recovered.
Required Scope
events:writeQuestions
Manage questions within events.
/events/{eventId}/questionsList all questions for an event.
Required Scope
questions:readQuery Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page numberDefault: 1 |
limit | integer | Items per page (max 100)Default: 20 |
status | string | Filter by status: DEFAULT, SELECTED, ANSWERED, REJECTED |
sortBy | string | Sort field: createdAt, voteCountDefault: createdAt |
sortOrder | string | Sort 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
}
}/events/{eventId}/questionsSubmit a new question to an event.
Required Scope
questions:writeRequest Body
| Parameter | Type | Description |
|---|---|---|
text* | string | Question text |
identifier | string | Custom identifier for the submitter |
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"
}'/events/{eventId}/questions/{questionId}Get a specific question by ID.
Required Scope
questions:read/events/{eventId}/questions/{questionId}Update a question's status (moderation).
Required Scope
questions:moderateRequest Body
| Parameter | Type | Description |
|---|---|---|
status* | string | New status: DEFAULT, SELECTED, ANSWERED, or REJECTED |
Question Statuses
| Status | Description |
|---|---|
DEFAULT | Pending moderation |
SELECTED | Approved, visible to audience |
ANSWERED | Question has been answered |
REJECTED | Rejected, 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" }'/events/{eventId}/questions/{questionId}Delete a question.
Required Scope
questions:moderateOrganization
Get information about your organization.
/organizationGet your organization's information including usage and limits.
Required Scope
organization:readExample 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"
}
}