{"openapi":"3.1.0","info":{"title":"PostMantis API","version":"1.0.0","description":"Public API for social media automation. List connected profiles, create and manage posts, upload media, and inspect publishing outcomes. All endpoints require Bearer token authentication using a PostMantis API key."},"servers":[{"url":"https://postmantis.com","description":"Configured server"}],"tags":[{"name":"Profiles","description":"Connected social accounts available for publishing. Agents list profiles first, then use profile ids when creating posts."},{"name":"Posts","description":"Create, read, update, cancel, and list posts. Supports publish-now and scheduled publishing across multiple providers."},{"name":"Uploads","description":"Two-phase direct-to-storage upload flow. Callers request a presigned URL, PUT bytes, then finalize to receive a verified artifact id for use in posts."},{"name":"Publishing Logs","description":"Read-only delivery event stream. Shows what happened to each post delivery (scheduled, published, failed, canceled) with timestamps and provider links."}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"PostMantis API key from the dashboard. Include as `Authorization: Bearer <key>`."}},"schemas":{"ProfilesListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"provider":{"type":"string","enum":["x","tiktok","pinterest"]},"status":{"type":"string","enum":["active","reauthRequired","disconnected"]},"username":{"type":"string"},"pictureUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"postsCount":{"type":"integer","minimum":0},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","provider","status","postsCount","createdAt","updatedAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false},"ProblemDetails":{"type":"object","properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer","exclusiveMinimum":0},"detail":{"type":"string"},"code":{"type":"string"},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"number"}]}},"message":{"type":"string"}},"required":["path","message"]}}},"required":["type","title","status","detail","code"],"additionalProperties":false},"ProfileEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"provider":{"type":"string","enum":["x","tiktok","pinterest"]},"status":{"type":"string","enum":["active","reauthRequired","disconnected"]},"username":{"type":"string"},"pictureUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"postsCount":{"type":"integer","minimum":0},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","name","provider","status","postsCount","createdAt","updatedAt"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"PaginatedPostsResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","settled","canceled","scheduled"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"artifactId":{"type":"string","format":"uuid"},"artifactStatus":{"type":"string","enum":["reserved","verified","rejected"]},"contentType":{"type":"string"},"url":{"type":"string","format":"uri"},"alt":{"type":"string"}},"required":["id","artifactId"],"additionalProperties":false}},"deliveries":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["x","tiktok","pinterest"]},"profileName":{"type":"string"},"status":{"type":"string","enum":["pending","published","failed","canceled"]},"providerOptions":{"type":"object","additionalProperties":{}},"profileId":{"type":"string","format":"uuid"},"scheduledAt":{"type":"string","format":"date-time"},"publishedAt":{"type":"string","format":"date-time"},"failedAt":{"type":"string","format":"date-time"},"providerPostId":{"type":"string"},"url":{"type":"string","format":"uri"},"errorMessage":{"type":"string"}},"required":["provider","profileName","status","providerOptions"],"additionalProperties":false}},"body":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"}},"required":["id","status","createdAt","updatedAt","media","deliveries"],"additionalProperties":false}},"pagination":{"type":"object","properties":{"page":{"type":"integer","minimum":0},"perPage":{"type":"integer","exclusiveMinimum":0},"total":{"type":"integer","minimum":0}},"required":["page","perPage","total"],"additionalProperties":false}},"required":["data","pagination"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"PostEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","settled","canceled","scheduled"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"artifactId":{"type":"string","format":"uuid"},"artifactStatus":{"type":"string","enum":["reserved","verified","rejected"]},"contentType":{"type":"string"},"url":{"type":"string","format":"uri"},"alt":{"type":"string"}},"required":["id","artifactId"],"additionalProperties":false}},"deliveries":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","enum":["x","tiktok","pinterest"]},"profileName":{"type":"string"},"status":{"type":"string","enum":["pending","published","failed","canceled"]},"providerOptions":{"type":"object","additionalProperties":{}},"profileId":{"type":"string","format":"uuid"},"scheduledAt":{"type":"string","format":"date-time"},"publishedAt":{"type":"string","format":"date-time"},"failedAt":{"type":"string","format":"date-time"},"providerPostId":{"type":"string"},"url":{"type":"string","format":"uri"},"errorMessage":{"type":"string"}},"required":["provider","profileName","status","providerOptions"],"additionalProperties":false}},"body":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"canceledAt":{"type":"string","format":"date-time"}},"required":["id","status","createdAt","updatedAt","media","deliveries"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"CreatePostRequest":{"type":"object","properties":{"post":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":5000},"scheduledAt":{"type":"string","format":"date-time"}},"additionalProperties":false},"profiles":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1},"media":{"type":"array","items":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid"},"alt":{"type":"string","minLength":1,"maxLength":1000}},"required":["artifactId"],"additionalProperties":false},"minItems":1,"maxItems":20},"providerOptions":{"type":"object","properties":{"x":{"type":"object","additionalProperties":{}},"tiktok":{"type":"object","additionalProperties":{}},"pinterest":{"type":"object","additionalProperties":{}}},"additionalProperties":false}},"required":["post","profiles"],"additionalProperties":false},"UpdatePostRequest":{"type":"object","properties":{"post":{"type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":5000},"scheduledAt":{"type":"string","format":"date-time"}},"additionalProperties":false},"media":{"type":"array","items":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid"},"alt":{"type":"string","minLength":1,"maxLength":1000}},"required":["artifactId"],"additionalProperties":false},"maxItems":20},"providerOptions":{"type":"object","properties":{"x":{"type":"object","additionalProperties":{}},"tiktok":{"type":"object","additionalProperties":{}},"pinterest":{"type":"object","additionalProperties":{}}},"additionalProperties":false}},"additionalProperties":false},"UploadPresignEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid"},"uploadUrl":{"type":"string","format":"uri"},"requiredHeaders":{"type":"object","additionalProperties":{"type":"string"}}},"required":["artifactId","uploadUrl","requiredHeaders"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"CreateUploadRequest":{"type":"object","properties":{"fileName":{"type":"string","minLength":1,"maxLength":255},"mimeType":{"type":"string","minLength":1,"maxLength":255},"fileSize":{"type":"integer","exclusiveMinimum":0,"maximum":157286400}},"required":["fileName","mimeType","fileSize"],"additionalProperties":false},"ArtifactEnvelope":{"type":"object","properties":{"data":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid"},"storageKey":{"type":"string"},"url":{"type":"string","format":"uri"},"createdAt":{"type":"string","format":"date-time"},"kind":{"type":"string","enum":["image","video"]},"mimeType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":0}},"required":["artifactId","storageKey","url","createdAt","kind","mimeType","sizeBytes"],"additionalProperties":false}},"required":["data"],"additionalProperties":false},"CompleteUploadRequest":{"type":"object","properties":{"artifactId":{"type":"string","format":"uuid"}},"required":["artifactId"],"additionalProperties":false},"PublishingLogResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deliveryId":{"type":"string","format":"uuid"},"postId":{"type":"string","format":"uuid"},"provider":{"type":"string","enum":["x","tiktok","pinterest"]},"type":{"type":"string","enum":["pending","published","failed","canceled"]},"occurredAt":{"type":"string","format":"date-time"},"postBody":{"type":"string"},"postScheduledAt":{"type":"string","format":"date-time"},"profileName":{"type":"string"},"releaseUrl":{"type":"string","format":"uri"},"providerPostId":{"type":"string"},"errorMessage":{"type":"string"}},"required":["id","deliveryId","postId","provider","type","occurredAt"],"additionalProperties":false}}},"required":["data"],"additionalProperties":false}},"parameters":{}},"paths":{"/api/v1/profiles":{"get":{"tags":["Profiles"],"operationId":"listProfiles","summary":"List connected profiles","description":"Returns all active publishing profiles visible to the authenticated API key. Use the returned profile ids when creating posts. Results are filtered by API-key scope if one is in use.","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"List of profiles available for posting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfilesListResponse"},"example":{"data":[{"id":"4339a6bc-9cd3-455e-8f91-df8bc63f12d7","name":"PostMantis on X","provider":"x","status":"active","username":"postmantis","postsCount":12,"createdAt":"2026-05-05T10:00:00.000Z","updatedAt":"2026-05-05T10:00:00.000Z"}]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/profiles/{id}":{"get":{"tags":["Profiles"],"operationId":"getProfile","summary":"Get a single profile","description":"Returns one profile by id, including connection status and publish history. Returns 404 if the profile is not visible to the caller's API-key scope.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Profile UUID"},"required":true,"description":"Profile UUID","name":"id","in":"path"}],"responses":{"200":{"description":"Profile detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileEnvelope"},"example":{"data":{"id":"4339a6bc-9cd3-455e-8f91-df8bc63f12d7","name":"PostMantis on X","provider":"x","status":"active","username":"postmantis","pictureUrl":"https://example.com/avatar.png","postsCount":12,"createdAt":"2026-05-05T10:00:00.000Z","updatedAt":"2026-05-05T10:00:00.000Z"}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"404":{"description":"Profile not found or not accessible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/not-found","title":"Not found","status":404,"detail":"Resource not found.","code":"notFound"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/profiles/{id}/disconnect":{"post":{"tags":["Profiles"],"operationId":"disconnectProfile","summary":"Disconnect a profile","description":"Permanently disconnects a social profile. Existing scheduled posts targeting this profile will fail at delivery time. Requires write permission.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Profile UUID"},"required":true,"description":"Profile UUID","name":"id","in":"path"}],"responses":{"204":{"description":"Profile disconnected successfully."},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"404":{"description":"Profile not found or not accessible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/not-found","title":"Not found","status":404,"detail":"Resource not found.","code":"notFound"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/posts":{"get":{"tags":["Posts"],"operationId":"listPosts","summary":"List posts","description":"Returns posts visible to the authenticated caller, with optional filtering by status, profile, provider, and scheduled date range. Supports paginated iteration.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["pending","settled","canceled","scheduled"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"array","items":{"type":"string","format":"uuid"}},"required":false,"name":"profileIds","in":"query"},{"schema":{"type":"array","items":{"type":"string","enum":["x","tiktok","pinterest"]}},"required":false,"name":"providers","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"scheduledAfter","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"scheduledBefore","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"default":0},"required":false,"name":"page","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"perPage","in":"query"}],"responses":{"200":{"description":"Paginated posts list.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedPostsResponse"},"example":{"data":{"data":[{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","body":"Ship small. Learn fast.","status":"settled","createdAt":"2026-05-05T10:00:00.000Z","updatedAt":"2026-05-05T10:00:00.000Z","media":[],"deliveries":[{"profileId":"4339a6bc-9cd3-455e-8f91-df8bc63f12d7","provider":"x","profileName":"PostMantis on X","status":"published","publishedAt":"2026-05-05T10:01:00.000Z","providerPostId":"1234567890","url":"https://x.com/postmantis/status/1234567890","providerOptions":{}}]}],"pagination":{"page":0,"perPage":20,"total":1}}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}},"post":{"tags":["Posts"],"operationId":"createPost","summary":"Create a post","description":"Creates a publish-now post when `post.scheduledAt` is omitted, or a scheduled post when `post.scheduledAt` is a future ISO-8601 datetime. Accepts JSON or multipart/form-data (for direct file uploads). Posts must have a body, media, or both. Use `/uploads` first if you want server-verified artifacts.","security":[{"BearerAuth":[]}],"requestBody":{"description":"Post creation payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"},"examples":{"publishTextNow":{"summary":"Publish now (text only)","value":{"post":{"body":"Ship small. Learn fast."},"profiles":["4339a6bc-9cd3-455e-8f91-df8bc63f12d7"]}},"scheduledText":{"summary":"Schedule text post","value":{"post":{"body":"Scheduled launch note.","scheduledAt":"2026-05-06T15:00:00.000Z"},"profiles":["4339a6bc-9cd3-455e-8f91-df8bc63f12d7"]}},"withMedia":{"summary":"Post with uploaded media","value":{"post":{"body":"Check out our new release."},"profiles":["4339a6bc-9cd3-455e-8f91-df8bc63f12d7"],"media":[{"artifactId":"b2c3d4e5-f6a7-8901-bcde-f23456789012","alt":"Product screenshot"}]}}}},"multipart/form-data":{"schema":{"$ref":"#/components/schemas/CreatePostRequest"},"examples":{"multipartWithFile":{"summary":"Multipart with file attachment","value":{"post":{"body":"Shipping today."},"profiles":["4339a6bc-9cd3-455e-8f91-df8bc63f12d7"],"media":[{"artifactId":"b2c3d4e5-f6a7-8901-bcde-f23456789012"}]}}}}}},"responses":{"201":{"description":"Post created and accepted for publishing workflow.","headers":{"Location":{"description":"URL of the newly created post.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostEnvelope"}}}},"400":{"description":"Invalid post request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/invalid-request","title":"Invalid request","status":400,"detail":"The request payload failed validation.","code":"invalidRequest"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"415":{"description":"Unsupported content type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unsupported-media-type","title":"Unsupported media type","status":415,"detail":"Unsupported content type. Use application/json or multipart/form-data.","code":"unsupportedMediaType"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/posts/{postId}":{"get":{"tags":["Posts"],"operationId":"getPost","summary":"Get a single post","description":"Returns full post state including media processing status and per-provider delivery outcomes. Omitted fields mean no value. Use this to poll delivery status after creation.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Post UUID"},"required":true,"description":"Post UUID","name":"postId","in":"path"}],"responses":{"200":{"description":"Post detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostEnvelope"},"example":{"data":{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","body":"Ship small. Learn fast.","status":"settled","createdAt":"2026-05-05T10:00:00.000Z","updatedAt":"2026-05-05T10:00:00.000Z","media":[],"deliveries":[{"profileId":"4339a6bc-9cd3-455e-8f91-df8bc63f12d7","provider":"x","profileName":"PostMantis on X","status":"published","publishedAt":"2026-05-05T10:01:00.000Z","providerPostId":"1234567890","url":"https://x.com/postmantis/status/1234567890","providerOptions":{}}]}}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"404":{"description":"Post not found or not accessible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/not-found","title":"Not found","status":404,"detail":"Resource not found.","code":"notFound"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}},"patch":{"tags":["Posts"],"operationId":"updatePost","summary":"Update a scheduled post","description":"Edits a future scheduled post before delivery starts. Only `scheduled` posts with a future `scheduledAt` can be updated. Set `post.scheduledAt: null` to publish immediately. Requires write permission.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Post UUID"},"required":true,"description":"Post UUID","name":"postId","in":"path"}],"requestBody":{"description":"Fields to update. At least one field must be provided.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePostRequest"},"examples":{"reschedule":{"summary":"Reschedule post","value":{"post":{"scheduledAt":"2026-05-07T09:00:00.000Z"}}},"publishScheduledPostNow":{"summary":"Publish scheduled post now","value":{"post":{"scheduledAt":null}}},"editBody":{"summary":"Edit body text","value":{"post":{"body":"Updated launch note."}}}}}}},"responses":{"200":{"description":"Post updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostEnvelope"}}}},"400":{"description":"Invalid update request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/invalid-request","title":"Invalid request","status":400,"detail":"The request payload failed validation.","code":"invalidRequest"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"404":{"description":"Post not found or not accessible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/not-found","title":"Not found","status":404,"detail":"Resource not found.","code":"notFound"}}}},"409":{"description":"Only future scheduled posts can be edited.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/conflict","title":"Conflict","status":409,"detail":"Resource is in a state that prevents this operation.","code":"conflict"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/posts/{postId}/cancel":{"post":{"tags":["Posts"],"operationId":"cancelPost","summary":"Cancel a scheduled post","description":"Cancels a scheduled post and its pending deliveries. Only posts in `scheduled` status that have not started delivery can be canceled. Requires write permission.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Post UUID"},"required":true,"description":"Post UUID","name":"postId","in":"path"}],"responses":{"200":{"description":"Post canceled successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostEnvelope"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"404":{"description":"Post not found or not accessible.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/not-found","title":"Not found","status":404,"detail":"Resource not found.","code":"notFound"}}}},"409":{"description":"Post is not in a cancelable state.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/conflict","title":"Conflict","status":409,"detail":"Resource is in a state that prevents this operation.","code":"conflict"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/uploads":{"post":{"tags":["Uploads"],"operationId":"createUpload","summary":"Request an upload URL","description":"Starts a two-phase upload. Returns reserved artifact id and presigned PUT URL. Caller uploads bytes directly to storage, then calls `POST /uploads/complete` with artifact id. Max file size is 150 MB.","security":[{"BearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"},"example":{"fileName":"launch-video.mp4","mimeType":"video/mp4","fileSize":12345678}}}},"responses":{"201":{"description":"Presigned upload URL created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadPresignEnvelope"},"example":{"data":{"artifactId":"b2c3d4e5-f6a7-8901-bcde-f23456789012","uploadUrl":"https://storage.example.com/...","requiredHeaders":{"content-type":"video/mp4"}}}}}},"400":{"description":"Invalid upload request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/invalid-request","title":"Invalid request","status":400,"detail":"The request payload failed validation.","code":"invalidRequest"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"415":{"description":"Unsupported content type.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unsupported-media-type","title":"Unsupported media type","status":415,"detail":"Unsupported content type. Use application/json or multipart/form-data.","code":"unsupportedMediaType"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/uploads/complete":{"post":{"tags":["Uploads"],"operationId":"completeUpload","summary":"Finalize an upload","description":"Verifies the uploaded object, promotes it to a verified artifact, and returns the artifact id and a temporary read URL. Use the artifact id in post media references.","security":[{"BearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadRequest"},"example":{"artifactId":"b2c3d4e5-f6a7-8901-bcde-f23456789012"}}}},"responses":{"200":{"description":"Upload verified and artifact created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArtifactEnvelope"},"example":{"data":{"artifactId":"b2c3d4e5-f6a7-8901-bcde-f23456789012","storageKey":"user-123/...","url":"https://cdn.example.com/...","createdAt":"2026-05-05T10:00:00.000Z","kind":"video","mimeType":"video/mp4","sizeBytes":12345678}}}}},"400":{"description":"Invalid or expired finalize token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/invalid-request","title":"Invalid request","status":400,"detail":"The request payload failed validation.","code":"invalidRequest"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"403":{"description":"API key lacks write permission.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/forbidden","title":"Forbidden","status":403,"detail":"The authenticated API key is not allowed to perform this action.","code":"forbidden"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}},"/api/v1/publish/logs":{"get":{"tags":["Publishing Logs"],"operationId":"listPublishingLogs","summary":"List publishing log entries","description":"Returns chronological delivery status history (pending, published, failed, canceled). Pending means accepted and waiting for dispatch or scheduled time.","security":[{"BearerAuth":[]}],"parameters":[{"schema":{"type":["integer","null"],"minimum":0,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"default":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Publishing log entries.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishingLogResponse"},"example":{"data":[{"id":"c3d4e5f6-a7b8-9012-cdef-345678901234","deliveryId":"d4e5f6a7-b8c9-0123-defa-456789012345","postId":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","postBody":"Ship small. Learn fast.","provider":"x","profileName":"PostMantis on X","type":"published","occurredAt":"2026-05-05T10:01:00.000Z","releaseUrl":"https://x.com/postmantis/status/1234567890","providerPostId":"1234567890"}]}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Authentication required.","code":"unauthorized"}}}},"429":{"description":"Rate limit exceeded.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"},"example":{"type":"https://postmantis.com/problems/rate-limited","title":"Too many requests","status":429,"detail":"Too many requests.","code":"rateLimited"}}}}}}}},"webhooks":{}}