Complete API documentation for the Planable Zapier Integration. This API enables automation workflows by connecting Planable with thousands of apps through Zapier.
Base URL: https://app.planable.io/api/integrations/zapier
Table of Contents
- Introduction
- Authentication
- Core Endpoints
- Webhooks
- Polling
- Request/Response Format
- Examples
- Reference
Introduction
The Planable Zapier API allows you to:
- Create posts in Planable workspaces automatically
- Upload media to your media library from external sources
- Receive real-time notifications when posts are approved, published, or scheduled
- Sync workspaces and pages with other tools
Quick Start
# 1. Authenticate and get access tokencurl -X POST <https://app.planable.io/api/integrations/zapier/auth/token> \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "grant_type=authorization_code" \\ -d "code=YOUR_AUTH_CODE" \\ -d "client_id=YOUR_CLIENT_ID" \\ -d "client_secret=YOUR_CLIENT_SECRET"# 2. Create a postcurl -X POST <https://app.planable.io/api/integrations/zapier/posts> \\ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_abc123" \\ -d "pageId=pg_def456" \\ -d "plainText=Hello from the API!"
Authentication
The API uses OAuth 2.0 for authentication with Bearer tokens.
OAuth Flow
1. User → Redirect to Planable login
GET /login?client_id={id}&redirect_uri={uri}&response_type=code&state={state}&integration=zapier
2. User logs in → Planable generates auth code
3. Zapier → Exchange code for tokens
POST /auth/token
4. API → Returns access_token + refresh_token
5. Zapier → Make API requests with access_token
Authorization: Bearer {access_token}
Get Access Token
Endpoint: POST /api/integrations/zapier/auth/token
Request (form-urlencoded):
grant_type=authorization_code
code={AUTH_CODE}
client_id={CLIENT_ID}
client_secret={CLIENT_SECRET}
redirect_uri={REDIRECT_URI}
Response:
{
"access_token": "64-character-hex-token",
"refresh_token": "64-character-hex-token",
"token_type": "Bearer",
"expires_in": 3600
}
Notes:
- Access tokens expire in 1 hour
- Auth codes expire in 10 minutes
- Refresh tokens never expire
Refresh Access Token
Endpoint: POST /api/integrations/zapier/auth/token
Request (form-urlencoded):
grant_type=refresh_token
refresh_token={REFRESH_TOKEN}
client_id={CLIENT_ID}
client_secret={CLIENT_SECRET}
Response:
{
"access_token": "new-access-token",
"refresh_token": "new-refresh-token",
"token_type": "Bearer",
"expires_in": 3600
}
Notes:
- Generates new access and refresh tokens
- Old tokens are invalidated
- Auto-refresh enabled in Zapier
Test Connection
Endpoint: GET /api/integrations/zapier/me
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Response:
{ "id": "user123", "email": "user@example.com", "name": "User Name"}
Core Endpoints
List Workspaces
Get all workspaces accessible to the authenticated user.
Endpoint: GET /api/integrations/zapier/workspaces
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Response:
[
{ "id": "wks_abc123", "name": "Marketing Team" },
{ "id": "wks_def456", "name": "Product Updates" }
]
Use case: Dynamic dropdown for workspace selection
List Pages
Get all pages (social media accounts) in a workspace.
Endpoint: GET /api/integrations/zapier/pages
Query Parameters:
-
workspaceId(required): Workspace ID
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Example:
GET /api/integrations/zapier/pages?workspaceId=wks_abc123
Response:
[
{ "id": "pg_123abc", "name": "Instagram - @company" },
{ "id": "pg_456def", "name": "Facebook - Company Page" }
]
Use case: Dynamic dropdown for page selection (depends on workspace)
Create Post
Create a new post in Planable.
Endpoint: POST /api/integrations/zapier/posts
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/x-www-form-urlencoded
Request Parameters:
-
workspaceId(required): Workspace ID -
pageId(required): Page ID -
plainText(required): Post content -
mediaUrl(optional): URL to image/video to attach
Example:
curl -X POST <https://app.planable.io/api/integrations/zapier/posts> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_abc123" \\ -d "pageId=pg_def456" \\ -d "plainText=Check out our new product!" \\ -d "mediaUrl=https://example.com/product.jpg"
Response:
{
"id": "post_xyz789",
"plainText": "Check out our new product!",
"type": "instagram", "classification": "post",
"pageId": "pg_def456",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:30:00.000Z"
}
Notes:
- Post created in draft state
- If
mediaUrlprovided, media is downloaded and attached synchronously - Media errors don’t fail post creation
- Maximum media size: 50MB
Upload Media
Upload media files to the workspace media library.
Endpoint: POST /api/integrations/zapier/media
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/x-www-form-urlencoded
Request Parameters:
-
workspaceId(required): Workspace ID -
mediaUrl(required): URL to media file (image or video)
Example:
curl -X POST <https://app.planable.io/api/integrations/zapier/media> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_abc123" \\ -d "mediaUrl=https://example.com/image.jpg"
Response:
{
"jobId": "job-abc-123",
"status": "processing",
"message": "Upload job created for 1 file. Media will be available shortly.",
"filesCount": 1
}
Notes:
- Processing is asynchronous
- Media available after processing completes
- Maximum file size: 50MB
- Triggers
media.newwebhook when complete
Get Recent Media
Get the most recent media upload from a workspace.
Endpoint: GET /api/integrations/zapier/media
Query Parameters:
-
workspaceId(required): Workspace ID -
limit(optional): Not currently used
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Response:
[
{
"id": "media_abc123",
"workspaceId": "wks_abc123",
"mediaType": "image",
"url": "<https://cdn.planable.io/media/image.jpg>",
"name": "photo.jpg",
"source": "zapier",
"createdAt": "2025-01-15T10:00:00.000Z",
"size": 1048576
}
]
Use case: Testing/polling for new media uploads
Webhooks
Webhooks provide real-time notifications when events occur in Planable workspaces.
Event Types
| Event | Triggers When | Additional Filtering |
|---|---|---|
activity.new |
Post activity occurs | By activityType
|
media.new |
Media uploaded successfully | None |
Activity Types
For activity.new events, you can filter by these activity types:
| Activity Type | Triggers When | Use Case |
|---|---|---|
addedPost |
Post created | New content notification |
approvedPost |
Post approved | Approval workflows |
postScheduledSet |
Post scheduled | Scheduling notifications |
postPublished |
Post auto-published | Publishing confirmation |
postPublishingError |
Publishing fails | Error notifications |
changedLabels |
Labels modified | Label tracking |
markedAsPublished |
Manually marked published | Manual publishing workflows |
Subscribe to Webhook
Endpoint: POST /api/integrations/zapier/hooks
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/x-www-form-urlencoded
Request Parameters:
-
targetUrl(required): Your webhook URL -
event(required):activity.newormedia.new -
workspaceId(required): Workspace ID -
activityType(optional): Foractivity.newevents only
Example - Subscribe to Post Approvals:
curl -X POST <https://app.planable.io/api/integrations/zapier/hooks> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "targetUrl=https://hooks.zapier.com/xyz" \\ -d "event=activity.new" \\ -d "workspaceId=wks_abc123" \\ -d "activityType=approvedPost"
Response:
{ "id": "hook-token-abc123" }
Notes:
- Save the
idto unsubscribe later - Hooks stored per workspace
- Maximum 5 concurrent webhook requests
- 10 second timeout per request
Unsubscribe from Webhook
Endpoint: DELETE /api/integrations/zapier/hooks/{hookId}
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Example:
curl -X DELETE <https://app.planable.io/api/integrations/zapier/hooks/hook-token-abc123> \\ -H "Authorization: Bearer YOUR_TOKEN"
Response:
{ "success": true }
Webhook Payloads
activity.new Webhook
Sent when a post activity occurs.
Payload Structure:
{
"id": "activity_xyz789",
"type": "approvedPost",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:30:00.000Z",
"posts": [
{
"id": "post_xyz789",
"plainText": "Post content here",
"type": "instagram",
"classification": "post",
"pageId": "pg_def456",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:00:00.000Z",
"mediaType": "single-image",
"mediaUrls": ["<https://cdn.planable.io/media/image123.jpg>"],
"labels": [
{
"uuid": "label_abc",
"text": "Q1 Campaign",
"color": "#FF5733"
}
]
}
]
}
Media Types:
-
no-media: No media attached -
single-image: One image -
video: Video file -
multiple-images: Multiple images -
mixed-media: Mix of images and videos
Notes:
-
postsarray contains related posts -
mediaUrlsarray contains CDN URLs -
labelsarray contains post labels
media.new Webhook
Sent when media is successfully uploaded to library.
Payload Structure:
{
"id": "media_abc123",
"workspaceId": "wks_abc123",
"mediaType": "image",
"url": "<https://cdn.planable.io/media/image.jpg>",
"name": "product-photo.jpg",
"source": "zapier",
"createdAt": "2025-01-15T10:30:00.000Z",
"size": 1048576
}
Media Types: image, video
Polling
If webhooks aren’t suitable, you can poll for activities.
Get Recent Activities
Endpoint: GET /api/integrations/zapier/activities
Query Parameters:
-
workspaceId(required): Workspace ID -
activityType(required): Activity type to filter -
limit(optional): Not currently used
Headers:
Authorization: Bearer {ACCESS_TOKEN}
Example:
GET /api/integrations/zapier/activities?workspaceId=wks_abc123&activityType=approvedPost
Response:
{
"activities": [
{
"id": "activity_xyz789",
"type": "approvedPost",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:30:00.000Z",
"posts": [...]
}
]
}
Notes:
- Returns most recent activity only
- Same structure as webhook payload
- Use webhooks for real-time, polling for testing
Request/Response Format
Request Format
Content-Type: application/x-www-form-urlencoded
Authorization Header:
Authorization: Bearer {ACCESS_TOKEN}
Parameter Encoding: URL-encoded form data
Example:
curl -X POST {URL} \\ -H "Authorization: Bearer abc123..." \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_123" \\ -d "plainText=Hello World"
Response Format
Success Response (200 OK):
{ "id": "resource_123", "field": "value" }
Error Response (4xx, 5xx):
{ "error": "Error message describing what went wrong" }
HTTP Status Codes
| Code | Status | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid or missing parameters |
| 401 | Unauthorized | Invalid or expired token |
| 404 | Not Found | Resource not found |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
Error Handling:
- For 401 errors, refresh your access token
- For 429 errors, implement exponential backoff
- For 500 errors, retry with backoff
Examples
Example 1: Create Post with Media
Step 1: List Workspaces
curl -X GET <https://app.planable.io/api/integrations/zapier/workspaces> \\ -H "Authorization: Bearer YOUR_TOKEN"
Response:
[{ "id": "wks_abc123", "name": "Marketing Team" }]
Step 2: List Pages
curl -X GET "<https://app.planable.io/api/integrations/zapier/pages?workspaceId=wks_abc123>" \\ -H "Authorization: Bearer YOUR_TOKEN"
Response:
[{ "id": "pg_def456", "name": "Instagram - @company" }]
Step 3: Create Post
curl -X POST <https://app.planable.io/api/integrations/zapier/posts> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_abc123" \\ -d "pageId=pg_def456" \\ -d "plainText=Check out our new product launch! 🚀" \\ -d "mediaUrl=https://example.com/product.jpg"
Response:
{
"id": "post_xyz789",
"plainText": "Check out our new product launch! 🚀",
"type": "instagram",
"classification": "post",
"pageId": "pg_def456",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:30:00.000Z"
}
Example 2: Subscribe to Post Approvals
Step 1: Subscribe to Webhook
curl -X POST <https://app.planable.io/api/integrations/zapier/hooks> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "targetUrl=https://hooks.zapier.com/catch/123456/abcdef/" \\ -d "event=activity.new" \\ -d "workspaceId=wks_abc123" \\ -d "activityType=approvedPost"
Response:
{ "id": "hook-token-abc123" }
Step 2: Receive Webhook
When a post is approved, Planable sends:
{
"id": "activity_xyz789",
"type": "approvedPost",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T11:00:00.000Z",
"posts": [
{
"id": "post_abc123",
"plainText": "Approved post content",
"type": "facebook",
"classification": "post",
"pageId": "pg_def456",
"workspaceId": "wks_abc123",
"createdAt": "2025-01-15T10:00:00.000Z",
"mediaType": "single-image",
"mediaUrls": ["<https://cdn.planable.io/media/image.jpg>"],
"labels": [{ "uuid": "label_1", "text": "Q1 2025", "color": "#FF5733"}]
}
]
}
Step 3: Process Data
Extract the approved post:
const post = webhookPayload.posts[0];console.log(`Post ${post.id} was approved: ${post.plainText}`);
Example 3: Upload Media to Library
Step 1: Upload Media
curl -X POST <https://app.planable.io/api/integrations/zapier/media> \\ -H "Authorization: Bearer YOUR_TOKEN" \\ -H "Content-Type: application/x-www-form-urlencoded" \\ -d "workspaceId=wks_abc123" \\ -d "mediaUrl=https://example.com/campaign-photo.jpg"
Response:
{
"jobId": "job-abc-123",
"status": "processing",
"message": "Upload job created for 1 file. Media will be available shortly.",
"filesCount": 1
}
Step 2: Receive Webhook (if subscribed to media.new)
{
"id": "media_xyz789",
"workspaceId": "wks_abc123",
"mediaType": "image",
"url": "<https://cdn.planable.io/media/campaign-photo.jpg>",
"name": "campaign-photo.jpg",
"source": "zapier",
"createdAt": "2025-01-15T10:35:00.000Z",
"size": 1048576
}
Reference
All Endpoints
| Method | Path | Purpose | Auth Required |
|---|---|---|---|
| POST | /auth/token |
Get or refresh access token | No (client credentials) |
| GET | /me |
Get authenticated user | Yes |
| GET | /workspaces |
List workspaces | Yes |
| GET | /pages |
List pages in workspace | Yes |
| POST | /posts |
Create post | Yes |
| GET | /posts |
List recent posts | Yes |
| POST | /media |
Upload media | Yes |
| GET | /media |
Get recent media | Yes |
| POST | /hooks |
Subscribe to webhook | Yes |
| DELETE | /hooks/:id |
Unsubscribe webhook | Yes |
| GET | /activities |
Get recent activities | Yes |
Constraints & Limits
| Resource | Limit | Notes |
|---|---|---|
| Access Token Expiry | 1 hour | Auto-refresh enabled |
| Auth Code Expiry | 10 minutes | Single use |
| Media File Size | 50 MB | Per file |
| Webhook Timeout | 10 seconds | Per request |
| Concurrent Webhooks | 5 | Maximum parallel |
| Refresh Token | Never expires | Generate new on refresh |
Media Types
| Type | Description | URL Exposed |
|---|---|---|
no-media |
No media attached | No |
single-image |
One image | Yes |
video |
Video file | Yes |
multiple-images |
Multiple images | Yes |
mixed-media |
Images + videos | Yes |
| Other types | URL previews, carousels, GIFs | No |
Support
- API Issues: Contact Planable support
- Integration Help: Check Zapier documentation
- Bug Reports: Include request/response details and timestamps
Last Updated: November 2025 API Version: 1.0