pixPLace API for developers and AI agents
Publish posts and stories, upload media, read comments, statistics, followers and notifications from n8n, a script or an AI agent. One key acts for one account. The whole API is described in one public file.
Quick start in 3 steps
Base URL https://pixplace.space/api/v1. Every request except the two public lists carries Authorization: Bearer ppk_live_…. Bodies are JSON.
1. Get a key
Sign in to pixPLace, open Settings → Developer and press New Key. The full key is shown once: store it as a secret (an n8n credential, an environment variable). Up to 3 keys per account; revoke a key there at any time. A key never leaves its account: it cannot act for another one.
2. Upload a file
Media must be on a host the portal can render. The simplest way: let the server download a public URL with POST /api/v1/uploads/from-url. The answer holds data.publicUrl on cdn.pixplace.space. (Videos up to 200 MB: POST /api/v1/uploads, a presigned PUT.)
curl -X POST https://pixplace.space/api/v1/uploads/from-url \
-H "Authorization: Bearer ppk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: upload-exec-1001-item-0" \
-d '{
"url": "https://example.com/photos/living-room.jpg"
}'3. Create the post
POST /api/v1/posts with the publicUrl as attachments[].url. The same Idempotency-Key on a retry returns the original post instead of a duplicate (HTTP 200 and Idempotent-Replayed: true). The answer has the post url.
curl -X POST https://pixplace.space/api/v1/posts \
-H "Authorization: Bearer ppk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: quickstart-post-1" \
-d '{
"title": "Minimalist living room",
"attachments": [
{
"url": "https://cdn.pixplace.space/content/cm9x2k4ab0001ld0h5q7w3e2z/2026-10/3f1c2a9e-5b7d-4c11-9a7e-0b1c2d3e4f5a.jpg",
"type": "IMAGE",
"width": 1536,
"height": 1024,
"altText": "Bright minimalist living room with an oak table"
}
],
"description": "AI-generated interior concept",
"tags": [
"interior",
"minimal"
]
}'Optional: a story
The same publicUrl works for a story that disappears after 24 hours: POST /api/v1/stories with url and type.
curl -X POST https://pixplace.space/api/v1/stories \
-H "Authorization: Bearer ppk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: exec-1001-story-0" \
-d '{
"url": "https://cdn.pixplace.space/content/cm9x2k4ab0001ld0h5q7w3e2z/2026-10/3f1c2a9e-5b7d-4c11-9a7e-0b1c2d3e4f5a.jpg",
"type": "IMAGE"
}'All endpoints
23 operations. This table and openapi.json are generated from the same list, so they cannot disagree. Paths with {id} take the id (or, for posts, the slug) of your own object.
Posts
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| POST | POST /api/v1/posts | Publish a post (image, video or carousel). | 5/min per account, 50/day per key |
| GET | GET /api/v1/posts | List your own posts, newest first. | Not limited |
| GET | GET /api/v1/posts/{id} | Read one of your own posts by id or slug. | Reads are not write-limited |
| PATCH | PATCH /api/v1/posts/{id} | Change fields of one of your own posts. Send only what changes. | 30/min, 300/day per account (shared with the other edit/delete calls) |
| DELETE | DELETE /api/v1/posts/{id} | Delete one of your own posts. | 30/min, 300/day per account (shared with the other edit/delete calls) |
| GET | GET /api/v1/posts/{id}/stats | Likes and comments of one of your own posts per UTC day. | Reads are not write-limited |
Uploads
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| POST | POST /api/v1/uploads/from-url | Have the server download a public image or video and store it. | 20/min, 200/day per account |
| POST | POST /api/v1/uploads | Get a presigned URL to PUT a large file (up to 200 MB video) straight to storage. | 20/min, 200/day per account |
Stories
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| POST | POST /api/v1/stories | Publish a story (visible for 24 hours). | 5/min, 30/day per account |
| GET | GET /api/v1/stories | List your own active stories (the last 24 hours), newest first. | Reads are not write-limited |
| DELETE | DELETE /api/v1/stories/{id} | Delete one of your own active stories. | 30/min, 300/day per account (shared with the other edit/delete calls) |
Comments
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| GET | GET /api/v1/posts/{id}/comments | Read the comments under one of your own posts, page by page. | Reads are not write-limited |
| POST | POST /api/v1/posts/{id}/comments | Write a comment, or a reply to a comment, under one of your own posts — as your account. | 20/min, 200/day per account |
| GET | GET /api/v1/comments | The inbox: what other people wrote under any of your posts, newest first. | Reads are not write-limited |
| DELETE | DELETE /api/v1/comments/{id} | Delete a comment — moderation of your own posts. | 30/min, 300/day per account (shared with the other edit/delete calls) |
Account
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| GET | GET /api/v1/account | The profile and counters of the account that owns the key. | Reads are not write-limited |
| GET | GET /api/v1/account/stats | Growth of the account per UTC day: posts, likes, comments and new followers. | Reads are not write-limited |
| GET | GET /api/v1/followers | The people who follow your account, newest first. | Reads are not write-limited |
| GET | GET /api/v1/following | The people your account follows, newest first. | Reads are not write-limited |
| GET | GET /api/v1/notifications | The notifications of your account (likes, comments, follows, system), newest first. | Reads are not write-limited |
| POST | POST /api/v1/notifications/read | Mark notifications as read. | 60/min, 5000/day per account |
Taxonomy
| Method | Endpoint | What it does | Limit |
|---|---|---|---|
| GET | GET /api/v1/categoriespublic | All category slugs accepted by `categories` in POST /api/v1/posts. | Public, no key |
| GET | GET /api/v1/nichespublic | The niche taxonomy with live post counts. | Public, no key |
Recipes
n8n: three HTTP Request nodes
Create one Header Auth credential (Name Authorization, Value Bearer ppk_live_…) and use it in all nodes. Turn Retry On Fail on (3 tries, 5000 ms): the Idempotency-Key makes the repeat safe.
- Node 1 — Upload from URL. Method / URL:
POST https://pixplace.space/api/v1/uploads/from-url. Body (JSON, expression):{{ JSON.stringify({ url: $json.imageUrl }) }}. HeaderIdempotency-Key: upload-{{ $execution.id }}-{{ $itemIndex }}. - Node 2 — Create post.
POST https://pixplace.space/api/v1/posts, headerIdempotency-Key: post-{{ $execution.id }}-{{ $itemIndex }}. Connect it directly after node 1; the body takespublicUrlfrom node 1:
{{ JSON.stringify({
title: $('Source item').item.json.title,
attachments: [{ url: $json.data.publicUrl, type: $json.data.type }],
description: $('Source item').item.json.description
}) }}Node 3 (optional) — Create story. POST https://pixplace.space/api/v1/stories, header Idempotency-Key: story-{{ $execution.id }}-{{ $itemIndex }}, body:
{{ JSON.stringify({ url: $('Upload from URL').item.json.data.publicUrl, type: $('Upload from URL').item.json.data.type }) }}To see a 429 in the workflow instead of an error, set Options → Response → Include Response Headers and Status and Never Error, then wait {{ $json.headers["retry-after"] }} seconds before the retry.
AI agent: copy this prompt
Give it to your agent (Claude, ChatGPT, a custom tool-calling bot) together with the key as a secret. The agent reads the spec itself: every operation, field, limit and error is in https://pixplace.space/api/v1/openapi.json.
Use the OpenAPI spec at https://pixplace.space/api/v1/openapi.json to call the pixPLace API.
Authenticate every request except GET /api/v1/categories and GET /api/v1/niches with the header
"Authorization: Bearer <PIXPLACE_API_KEY>" (a ppk_live_… key from Settings → Developer; never print or log it).
To publish: upload each file with POST /api/v1/uploads/from-url, then create the post with POST /api/v1/posts,
using data.publicUrl as attachments[].url and its type as attachments[].type.
Send an Idempotency-Key header on every create call and REUSE the same key when you retry.
On 429 or 503 wait the number of seconds in the Retry-After header before retrying; on 400 fix the request, do not retry it.
Before you promise a metric or action, check x-unavailable in the spec: what is listed there does not exist.Errors and retries
Errors are JSON: { "error": "…" }. Branch on the HTTP status, not on the text. A 429 also carries scope (minute or day), retryAfter and the limits.
| Status | Meaning | What to do |
|---|---|---|
| 400 | The request is invalid. The message names the field. Nothing was written, no quota was spent. | Fix the request. Do not retry it unchanged. |
| 401 | Missing, malformed or revoked API key. | Check the Authorization header and the key in Settings → Developer. |
| 404 | The post, story or comment does not exist, is not yours, or is hidden. Never 403. | On DELETE treat it as "already gone". |
| 409 | The Idempotency-Key was already used with a different body. | Use a new key for new content, or repeat the original request unchanged. |
| 413 | The file or the JSON body is too large. | Use POST /api/v1/uploads for videos above the from-url limit. |
| 415 | The file is not JPEG, PNG, WebP, MP4 or WebM (decided by its content). | Convert the file. |
| 429 | A limit was reached. The header Retry-After and the body field retryAfter say how many seconds to wait. | Wait, then repeat with the SAME Idempotency-Key. A daily limit means: stop and alert. |
| 500 | Unexpected error. No details are exposed. | Retry later; with a create call reuse the same Idempotency-Key. |
| 502 | The source URL of an upload could not be downloaded. | Check that the URL is public and answers 200. |
| 503 | The database or storage is momentarily unavailable. Retry-After: 5. | Retry with the SAME Idempotency-Key. Do not blindly retry POST comments: read the list first. |
| 504 | The source URL did not answer in time. | Try a faster host, or upload the file with POST /api/v1/uploads. |
Idempotency-Key
- Accepted by
POST /api/v1/posts,POST /api/v1/storiesandPOST /api/v1/uploads/from-url. 1–128 characters from A–Z a–z 0–9 . _ : - ; anything else is a 400. - A repeat from the same account returns the ORIGINAL result with HTTP 200 and the header
Idempotent-Replayed: true; a first success is 201. A replay spends no quota. - Retry a 429, a 503 or a timeout with the SAME key. For a new item use a new key. In n8n:
{{ $execution.id }}-{{ $itemIndex }}. POST /api/v1/posts/{id}/commentshas NO idempotency: a repeat creates a duplicate comment. After a timeout read the list first.
Limits
Creating a post: 5 per minute per account and 50 per day per key (resets at 00:00 UTC). The other write limits are counted per account; reads are not write-limited. Counters of uploads, edits, comments and notifications live in the memory of the server process and reset when it restarts: they are a brake against runaway automations, not an exact quota.
| Limit | Applies to |
|---|---|
| 5/min per account, 50/day per key | POST /posts |
| 30/min, 300/day per account (shared with the other edit/delete calls) | PATCH /posts/{id} · DELETE /posts/{id} · DELETE /stories/{id} · DELETE /comments/{id} |
| 20/min, 200/day per account | POST /uploads/from-url · POST /uploads · POST /posts/{id}/comments |
| 5/min, 30/day per account | POST /stories |
| 60/min, 5000/day per account | POST /notifications/read |
What is not available yet
Said plainly, so you (or your agent) do not look for it. The machine-readable list is x-unavailable in openapi.json: multiAccountKey, hideComment, editComment, changePostMedia, followActions, views, saves, deeplinkClicks, profileViews, dailyShares, mcpTools.
- Views, saves and deeplink clicks: the platform does not collect them, so /stats cannot report them (the response says so in `unavailable` instead of returning zeros).
- Account-level views, saves, deeplink clicks and profile views: not collected either, so /account/stats lists them in `unavailable` and has no numbers for them.
- Per-day shares: shares are only a running total.
- Hiding comments (keeping them but not showing them): not available yet — a hidden flag needs a new column and comes in a later phase. For now the only moderation is deleting a comment.
- Editing a comment, reactions to comments and a count of reactions by kind: not available through the API.
- Filtering comments by author or text, or reading them newest first for a single post: not available. The inbox (GET /comments) is the newest-first view across all your posts.
- One key for several accounts: a key always acts for its one owner. Managing several accounts with one key is planned for later.
- Changing the media of a post: delete the post and create a new one.
- Following or unfollowing, removing a follower, blocking: followers and following are read-only. Notifications are read-only too, apart from marking them as read; there is no deleting them.
- MCP: the Social API is REST only. There are no MCP tools for these endpoints; use HTTP with the API key (n8n HTTP Request node, curl).
- Statistics per country, device or traffic source, and anything older than 90 days in one request: not available (ask for several ranges).
- Notifying the author of a comment you reply to: the site does not do it either.
Machine-readable and further reading
- https://pixplace.space/api/v1/openapi.json — OpenAPI 3.1, public, no key, CORS open, cached 5 minutes.
- https://pixplace.space/llms.txt — what pixPLace is, for language models.
- Settings → Developer — create and revoke keys; interactive examples in your language.
- Server:
https://pixplace.space