# Cancel post Source: https://docs.postonce.to/api-reference/cancel-post /openapi/public-api.yaml post /v1/posts/{id}/cancel Cancels a scheduled or still-pending post without deleting its aggregate record or already published social content. # Connect account Source: https://docs.postonce.to/api-reference/connect-account /openapi/public-api.yaml post /v1/accounts/connect/{platform} Computes a five-minute browser authorization URL bound to the authenticated profile without connecting or changing an account. Open the returned URL in a separate browser step to authorize the provider; then list accounts to verify connection. Depending on platform, the browser uses provider OAuth or a PostOnce-hosted credential or signer flow. Never enter provider credentials in chat. # Create a workflow Source: https://docs.postonce.to/api-reference/create-a-workflow /openapi/public-api.yaml post /v1/workflows Creates a future-content cross-post workflow from one source account to one or more target accounts. Use `settings.content_filters` to limit which future posts are eligible. # Create draft Source: https://docs.postonce.to/api-reference/create-draft /openapi/public-api.yaml post /v1/drafts Saves content and optional media or destinations without publishing or scheduling it. Reuse an Idempotency-Key when retrying. # Create post Source: https://docs.postonce.to/api-reference/create-post /openapi/public-api.yaml post /v1/posts Creates one logical post that can target multiple connected accounts. Include `publish_at` to schedule it instead of sending immediately. # Create upload URL Source: https://docs.postonce.to/api-reference/create-upload-url /openapi/public-api.yaml post /v1/media/uploads Creates a signed upload URL and media_id. Upload raw file bytes with PUT to data.upload.signedUrl, then call get_media with that media_id and pass the returned data.public_url as media[].url when creating a post or draft. URL creation alone does not upload bytes. Treat the signed URL as a temporary credential; do not open it in a browser. # Delete a workflow Source: https://docs.postonce.to/api-reference/delete-a-workflow /openapi/public-api.yaml delete /v1/workflows/{id} Deletes a workflow and any queued workflow items linked to it. # Delete post Source: https://docs.postonce.to/api-reference/delete-post /openapi/public-api.yaml delete /v1/posts/{id} Cancels a scheduled or still-pending post without deleting its aggregate record or already published social content. This is functionally equivalent to cancel_post. # Disconnect account Source: https://docs.postonce.to/api-reference/disconnect-account /openapi/public-api.yaml delete /v1/accounts/{id} Removes PostOnce access to an owned social account. Most account records are deleted; Farcaster and Nostr records remain disconnected and disabled with credentials cleared. Farcaster signer revocation requires a separate provider step; Nostr remote-signer logout is best effort. This does not delete published social content. # Get draft Source: https://docs.postonce.to/api-reference/get-draft /openapi/public-api.yaml get /v1/drafts/{id} Returns one draft owned by the authenticated API-key profile. # Get media Source: https://docs.postonce.to/api-reference/get-media /openapi/public-api.yaml get /v1/media/{id} Resolves a previously returned `media_id` into its storage path and public URL. # Get post Source: https://docs.postonce.to/api-reference/get-post /openapi/public-api.yaml get /v1/posts/{id} Returns one aggregate post with per-target delivery state. # Get workflow Source: https://docs.postonce.to/api-reference/get-workflow /openapi/public-api.yaml get /v1/workflows/{id} Returns one workflow by ID. # List accounts Source: https://docs.postonce.to/api-reference/list-accounts /openapi/public-api.yaml get /v1/accounts Returns all social accounts owned by the API key profile, including disconnected accounts. # List drafts Source: https://docs.postonce.to/api-reference/list-drafts /openapi/public-api.yaml get /v1/drafts Lists unscheduled drafts owned by the authenticated API-key profile. # List posts Source: https://docs.postonce.to/api-reference/list-posts /openapi/public-api.yaml get /v1/posts Lists aggregate public posts for the authenticated profile. # List workflows Source: https://docs.postonce.to/api-reference/list-workflows /openapi/public-api.yaml get /v1/workflows Lists all workflows owned by the authenticated profile. # Publish now Source: https://docs.postonce.to/api-reference/publish-now /openapi/public-api.yaml post /v1/posts/{id}/publish Starts publishing a scheduled post immediately and returns the aggregate in processing state. # Update a workflow Source: https://docs.postonce.to/api-reference/update-a-workflow /openapi/public-api.yaml put /v1/workflows/{id} Updates a future-content workflow configuration, including activation state, target accounts, and optional `settings.content_filters`. # Update draft Source: https://docs.postonce.to/api-reference/update-draft /openapi/public-api.yaml patch /v1/drafts/{id} Updates, archives, restores, or marks a draft ready using updated_at as a compare-and-swap version. # Update post Source: https://docs.postonce.to/api-reference/update-post /openapi/public-api.yaml patch /v1/posts/{id} Updates a scheduled post before it runs. # v1 changelog Source: https://docs.postonce.to/changelog/v1 Release notes for the PostOnce Public API v1. ## 1.0.0-alpha Initial public API release with support for: * Accounts * Media uploads * Aggregate posts * Scheduled posts * Workflows Known v1 limitations: * no webhooks * no workspaces * no sessionless OAuth completion flow * no top-level post-results collection # Authentication Source: https://docs.postonce.to/getting-started/authentication Authenticate requests to the PostOnce Public API with dashboard-generated API keys. Send your API key as a bearer token on every request: ```http theme={null} Authorization: Bearer po_live_xxxxx_xxxxx ``` ## Create an API key 1. Sign in to the [PostOnce dashboard](https://postonce.to/dashboard). 2. Open **Preferences**. 3. Scroll to the **API Keys** section. 4. Enter a key name. 5. Choose the scopes the key should have. 6. Click **Create API key**. 7. Copy the token immediately and store it somewhere safe. If you lose the token, create a new key and revoke the old one. ## Scopes Current supported scopes: * `accounts:read` * `accounts:write` * `media:read` * `media:write` * `posts:read` * `posts:write` * `workflows:read` * `workflows:write` If a key is missing a required scope, the API returns a `403` error with code `missing_scope`. ## Verify your key ```bash theme={null} curl -s \ -H "Authorization: Bearer po_live_xxxxx_xxxxx" \ https://postonce.to/api/public/v1/accounts ``` # Data structures Source: https://docs.postonce.to/getting-started/data-structures Learn the main objects returned by the PostOnce Public API. These are the core objects you will work with most often when using the PostOnce Public API. ## Account Represents a connected social account owned by the API key profile. ```json theme={null} { "id": "86d8fe99-0332-433b-a6e4-502c788490be", "platform": "facebook", "username": "PostOnce", "avatar_url": "https://example.com/avatar.jpg", "status": "active", "created_at": "2025-11-04T22:25:00.082736+00:00", "updated_at": "2025-11-05T04:24:25.939628+00:00" } ``` `id` is the stable identifier you reuse when creating posts and workflows. ## Media Represents uploaded or referenced media attached to a post. ```json theme={null} { "url": "https://example.com/image.png", "type": "image", "width": 1200, "height": 630, "size": 148320 } ``` Upload endpoints return a `media_id` for storage lookups. Post creation currently accepts URL-based media objects. ## Post A `Post` is the main aggregate resource in the API. One public post can target multiple connected accounts. ```json theme={null} { "id": "1b2d6f18-8fd4-49df-a1b4-8c1f3aa9e8f5", "content": "Shipping the public API today.", "external_id": "launch-001", "origin": "public_api", "status": "scheduled", "publish_at": "2026-04-01T14:00:00.000Z", "created_at": "2026-03-30T15:15:48.28116+00:00", "media": [ { "url": "https://example.com/image.png", "type": "image", "width": 1200, "height": 630, "size": 148320 } ], "targets": [ { "account_id": "account-1", "platform": "facebook", "username": "PostOnce", "status": "scheduled", "target_post_id": "target-row-1", "platform_post_id": null, "platform_post_url": null, "error": null, "scheduled_time": "2026-04-01T14:00:00.000Z" } ] } ``` ### Post status Aggregate post status is derived from the per-target rows: * `queued` * `scheduled` * `processing` * `published` * `partial` * `failed` * `cancelled` ## Workflow A `Workflow` maps one source account to one or more target accounts. ```json theme={null} { "id": "9b32984d-8c8c-4f5c-8568-5d6a3a5c0ecb", "profile_id": "d8bd4cfb-a766-40ab-a749-e06fff57178f", "source_account_id": "86d8fe99-0332-433b-a6e4-502c788490be", "target_account_ids": [ "69a22f08-d66b-4c18-bb9d-054659333788" ], "name": "Workflow A to B", "description": null, "is_active": true, "future_content_enabled": true, "settings": { "content_filters": { "types": { "text": true, "image": true, "quote": false, "video": true }, "hashtags": { "exclude": [], "include": [] } } }, "last_checked": null, "last_enabled_at": "2026-03-30T15:15:48.164+00:00", "created_at": "2026-03-30T15:15:48.28116+00:00", "updated_at": "2026-03-30T15:15:48.28116+00:00" } ``` `derived_status` is a workflow-specific status, not the same as aggregate post status. # Errors Source: https://docs.postonce.to/getting-started/errors Understand the PostOnce Public API response envelope and common error codes. Successful responses use: ```json theme={null} { "data": {} } ``` Errors use: ```json theme={null} { "error": { "code": "missing_scope", "message": "Missing required scope: posts:write" } } ``` ## Common error codes * `invalid_api_key` * `missing_scope` * `plan_not_allowed` * `account_limit_reached` * `workflow_limit_reached` * `invalid_targets` * `inactive_target` * `invalid_media_id` # Rate limits Source: https://docs.postonce.to/getting-started/rate-limits Understand plan-based request limits and product limits in the PostOnce Public API. The public API enforces request limits separately from product limits. ## Request limits * `Creator`: `60` requests per minute * `Pro`: `300` requests per minute ## Product limits Your plan also controls how many product resources you can use through the API. These limits are enforced using the same plan configuration used by the dashboard. If you reach a plan cap, the API returns a `403` with a specific error code such as `account_limit_reached` or `workflow_limit_reached`. ## Retry guidance * Use `Idempotency-Key` on `POST /v1/posts` when retrying a post creation request. * Back off and retry on transient failures instead of sending bursts. # Response format Source: https://docs.postonce.to/getting-started/response-format Understand the standard success and error envelopes used by the PostOnce Public API. The PostOnce Public API uses a consistent response envelope across resources. ## Success responses Successful responses return a `data` object: ```json theme={null} { "data": { "id": "post_123", "status": "scheduled" } } ``` List responses may also include `meta`: ```json theme={null} { "data": [], "meta": { "next_cursor": null } } ``` ## Error responses Errors return an `error` object: ```json theme={null} { "error": { "code": "missing_scope", "message": "Missing required scope: posts:write" } } ``` Some errors include `details`: ```json theme={null} { "error": { "code": "invalid_request", "message": "Request validation failed.", "details": { "field": "publish_at" } } } ``` ## Idempotency Use `Idempotency-Key` on `POST /v1/posts` when retrying create requests. * Same key + same request body returns the stored result * Same key + different request body returns `409` This lets clients retry safely without creating duplicate post jobs. # Create a workflow Source: https://docs.postonce.to/guides/create-a-workflow Create a cross-post workflow with the PostOnce Public API. Use workflows to turn one connected account into the source for one or more target accounts. Optional `settings.content_filters` lets you restrict which future source posts are eligible by content type or hashtag rules. ```bash theme={null} curl -s \ -H "Authorization: Bearer po_live_xxxxx_xxxxx" \ -H "Content-Type: application/json" \ -X POST https://postonce.to/api/public/v1/workflows \ -d '{ "name": "Instagram to Facebook", "source_account_id": "source-account-id", "target_account_ids": ["target-account-id"], "is_active": true }' ``` ## Plan limits Workflow creation respects the same plan caps used by the dashboard. If you exceed your workflow limit, the API returns: ```json theme={null} { "error": { "code": "workflow_limit_reached", "message": "You have reached the maximum number of workflows for your plan." } } ``` # Create your first post Source: https://docs.postonce.to/guides/create-your-first-post Publish one logical post to multiple connected accounts with the PostOnce Public API. This example publishes one logical post to two connected accounts. ```bash theme={null} curl -s \ -H "Authorization: Bearer po_live_xxxxx_xxxxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: launch-001" \ -X POST https://postonce.to/api/public/v1/posts \ -d '{ "content": "Shipping the public API today.", "external_id": "launch-001", "targets": [ { "account_id": "account-1" }, { "account_id": "account-2", "content_override": "Shorter version for X" } ] }' ``` ## What happens next * PostOnce creates one aggregate public post * the request fans out internally to per-account rows * each target is delivered through the same Trigger-backed posting pipeline used by the dashboard ## Idempotency Use `Idempotency-Key` when creating posts so retries do not accidentally create duplicate publish jobs. # Save RSS updates as drafts Source: https://docs.postonce.to/guides/rss-to-draft Create reviewable PostOnce drafts from feed items with the API or native Zapier action, using stable retry keys. Save an article title and link as an inbox draft, then review it before publishing. This first workflow needs no destination accounts or media. Creating a draft does not schedule or publish a social post. Use a PostOnce plan with API access and a dedicated [API key](/getting-started/authentication). Grant `posts:write` to create drafts and `posts:read` to retrieve them. The Zapier connection test also needs `accounts:read`. Keep the key in your client's private credential store, never in feed data or shared workflow fields. ## Choose a stable source key Build one key from a fixed feed prefix and the item's immutable GUID, for example `rss-draft:product-news:article-42`. If the feed has no GUID, use its stable article URL. The full key must be a nonblank string of at most 200 characters. If your identifiers are longer, use a deterministic digest of the feed identity and GUID rather than truncating away uniqueness. Keep that key for every retry of the same item. Do not use the current time, a random value, or a new key merely because a response was lost. A new article needs its own identity. Final content should be the article title, a line break, and its link. ## Create through the API Send `POST https://postonce.to/api/public/v1/drafts` with your private Bearer credential, JSON content, and the source key in the `Idempotency-Key` header. The header is optional in the API but should always be supplied for this automated workflow. Example request body: ```json theme={null} { "content": "Our latest product update\nhttps://example.com/news/article-42" } ``` Example headers, with the credential value supplied privately by your client: ```text theme={null} Content-Type: application/json Idempotency-Key: rss-draft:product-news:article-42 Authorization: Bearer ``` Read `data.id` from the creation response and store it with the source item. A successful first create returns HTTP 201 and a draft whose status is `inbox`. Retrieve that exact draft with `GET https://postonce.to/api/public/v1/drafts/{id}`, substituting the returned ID. Do not guess an ID or create another draft just to inspect the result. Review it in [PostOnce drafts](https://postonce.to/dashboard/posts/drafts). If adding optional destinations through the API later, use `selected_account_ids` with actual connected account UUIDs. Saving those selections still does not publish. ## Use native Zapier actions The [private PostOnce invitation](https://zapier.com/developer/public-invite/246101/073073858af32d4ba9fd68ec7877dc8f/) enables the native app in your Zapier account. It is not a public-directory approval or an importable Zap template. 1. Choose **RSS by Zapier → New Item in Feed**, set your feed URL, and test the trigger to load an actual item. 2. Add **PostOnce → Create Draft**. Save your API key in the private PostOnce connection's **API Key** field. 3. Map **Source Event Key** to `rss-draft:your-feed:` followed by the item's GUID, or a stable article URL when no GUID exists. Keep the prefix fixed and the complete string within 200 characters. 4. Map **Final Content** to the title, a line break, and the article link. Leave destination accounts and media empty for this first draft. 5. Test the action and inspect its returned `id` and `inbox` status. Optionally add **Find Draft by ID**, mapping the actual ID from Create Draft. Native Zapier actions expose the resource fields directly, while raw REST responses wrap them in `data`. Review the saved draft before deciding whether to enable your Zap. Testing the workflow does not turn it on. Once intentionally enabled, inspect Zapier history to confirm incoming items produce the expected drafts. Keep the key out of ordinary action inputs, RSS fields, and shared screenshots. ## Retry without duplicating Reuse the same key, credential, and unchanged JSON body. A matching replay returns the saved result. Deduplication is scoped to the PostOnce profile, API-key identity, endpoint, method, and key; rotating the API key changes that scope. Inspect earlier drafts before replaying old events with a new credential. * `409 idempotency_key_reused`: the key was used with different content. Inspect the earlier result and reconcile the change instead of inventing a fresh key to bypass the conflict. * `409 idempotency_request_in_progress`: an earlier request is still being processed. Keep its identity while investigating or retrying; do not issue a competing write with a new key. * A timeout or lost response is not proof that creation failed. Check a known returned ID, or retry with the original identity and body. * `401`: reconnect or replace the invalid credential. `403`: check the required scopes and plan entitlement. Credential replacement does not preserve the old key's deduplication scope. Review the [error format](/getting-started/errors) and [rate limits](/getting-started/rate-limits). In Zapier, let native throttling retain the original mapped input rather than adding a second write loop. ## Choose accounts and media for later actions `GET https://postonce.to/api/public/v1/accounts` requires `accounts:read` and returns accounts in `data`. Each account includes `id`, `platform`, `media_requirements`, and `capabilities` (which can be null). There is no separate capabilities endpoint in this API. | Field | How to use it | | --------------------------------------------- | ------------------------------------------------------------------------------------------ | | `capabilities.destination` | Must be `true` when choosing a publishing destination. | | `capabilities.source` | Must be `true` when choosing a crossposting source. | | `capabilities.text`, `images`, `video` | Check support for the content you intend to send. | | `capabilities.replies`, `threads`, `backfill` | Check the relevant feature before requesting it; do not assume every platform supports it. | | `capabilities.connection_mode` | Describes the account's platform connection mode. | | `media_requirements` | Inspect the current platform-specific media constraints before preparing a file or URL. | An empty account list is a valid authenticated response and does not prevent creating the text-only draft above. Do not treat the first social account as the identity of the connected PostOnce profile. Use the returned account IDs and capability booleans when selecting destinations later; missing or null capabilities do not establish support. A public media URL must meet the selected platform's requirements. For a local file, use the documented media upload operations, actually upload the bytes to the signed URL, then resolve the asset's `public_url`. Do not send the PostOnce Bearer key to a signed storage URL or treat a local path as uploaded media. See the Media API reference in the sidebar. Publishing is a separate action; a queued post is still waiting for delivery. # Schedule a post Source: https://docs.postonce.to/guides/schedule-a-post Schedule a future post with the PostOnce Public API. Add `publish_at` to create a scheduled post. ```bash theme={null} curl -s \ -H "Authorization: Bearer po_live_xxxxx_xxxxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: scheduled-launch-001" \ -X POST https://postonce.to/api/public/v1/posts \ -d '{ "content": "Scheduled launch note", "publish_at": "2026-04-01T14:00:00.000Z", "targets": [ { "account_id": "account-1" } ] }' ``` ## Supported follow-up actions * `GET /v1/posts/{id}` to inspect the aggregate scheduled post * `PATCH /v1/posts/{id}` to update it before it runs * `POST /v1/posts/{id}/publish` to run it now * `POST /v1/posts/{id}/cancel` or `DELETE /v1/posts/{id}` to cancel it # Introduction Source: https://docs.postonce.to/introduction Get started with the PostOnce Public API. Build social publishing automations with the same engine that powers the PostOnce dashboard. Use the PostOnce Public API to: * publish one post to multiple connected accounts * schedule posts for later * automate cross-post workflows between accounts * manage posts and workflows programmatically from scripts, apps, and agents ## Why use the PostOnce API * **One logical post can target many accounts.** You send one post request and PostOnce handles the per-account fan-out. * **The API uses the same posting pipeline as the dashboard.** Immediate and scheduled publishing both run through the same Trigger-backed delivery path. * **The API stays resource-focused.** You work with accounts, media, posts, and workflows instead of low-level delivery records. ## Base URL ```text theme={null} https://postonce.to/api/public ``` ## Authentication All requests use a dashboard-generated API key: ```http theme={null} Authorization: Bearer po_live_xxxxx_xxxxx ``` See [Authentication](/getting-started/authentication) for scopes and plan access details. ## Recommended workflow 1. List your connected accounts. 2. Upload media if you need a signed upload target. 3. Create a post or workflow. 4. Read the returned resource to inspect status and next actions. ## Quick start Create a post that targets two connected accounts: ```bash theme={null} curl -s \ -H "Authorization: Bearer po_live_xxxxx_xxxxx" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: launch-001" \ -X POST https://postonce.to/api/public/v1/posts \ -d '{ "content": "Shipping the public API today.", "external_id": "launch-001", "targets": [ { "account_id": "account-1" }, { "account_id": "account-2" } ] }' ``` ## Next steps * Start with [Authentication](/getting-started/authentication) * Review [Response format](/getting-started/response-format) * Learn the shared [Data structures](/getting-started/data-structures) * Review [Rate limits](/getting-started/rate-limits) * Try [Create your first post](/guides/create-your-first-post) # PostOnce MCP Source: https://docs.postonce.to/mcp/docs Connect an MCP client to PostOnce, discover your social accounts, publish posts and inspect delivery, or create automatic crossposting workflows. Connect a supported MCP client to the social accounts and workflows you manage in PostOnce. Start with the [MCP setup instructions](https://postonce.to/integrations) for the recommended connection method. * Endpoint: `https://postonce.to/mcp` * Transport: Streamable HTTP * Manual authentication: `Authorization: Bearer ` The hosted server forwards your credential to the Public API for each tool operation. Your existing plan access and credential scopes apply. A custom configuration is separate from an official client directory listing. ## Prepare your account Create a dedicated key in [Preferences → API keys](https://postonce.to/dashboard/preferences?tab=api-keys). Start with `accounts:read` to check the connection; add the relevant posts, media or workflow scopes for the actions you need. Keep the key in your client's private configuration or secret environment, never in a conversation or a committed project file. Connect your social accounts in [PostOnce](https://postonce.to/dashboard/accounts). An empty account list means the connection worked but no usable social accounts were returned. See [plans](https://postonce.to/pricing) for Public API entitlement. ## Other clients Use the endpoint, Streamable HTTP transport and private Authorization header above if your client supports them. A client that requires OAuth needs its own supported setup; an arbitrary JSON snippet does not establish compatibility. Consult the [integration directory](https://postonce.to/integrations) for available client instructions. ## First useful action Ask: **“Show my connected social accounts.”** The `list_accounts` and `list_active_accounts` tools return account IDs and platform capabilities. Check `media_requirements` for required media and input constraints before choosing a text, image or video post. These are platform-level constraints; the service still checks account permissions at the requested operation. For an authorized post: 1. Select actual returned account IDs and prepare the content. 2. Call `create_post` with the content and those targets. Use a future `publish_at` timestamp only when scheduling is intended. Use `create_draft` for a draft. 3. Call `get_post` with the returned ID and inspect every destination's actual status. A queued or scheduled post has not necessarily been published. 4. Review delivery and recovery in [publishing history](https://postonce.to/dashboard/posts/published). For automatic crossposting, inspect `list_workflows` first. Use `create_workflow` or `update_workflow` with the selected source and destination IDs, then read the saved rule with `get_workflow`. A new active workflow is configured to process future source content; its creation does not prove a source post has already been delivered. Review it in [Workflows](https://postonce.to/dashboard/workflows). ## Media with the hosted connection Pass a supported, publicly fetchable media URL to `create_post`, or upload a selected local file **from your client**: 1. Call `create_upload_url` with `filename` and `content_type`. 2. PUT the file bytes from the client to the returned `data.upload.signedUrl` using the matching content type. Check that upload succeeds. Do not send your PostOnce key to the storage host or expose the signed URL in chat/logs. 3. Call `get_media` with `data.media_id` and use the returned `public_url` in the post's media object. 4. Inspect the resulting post's delivery status. An allocated media ID alone is not proof that a file was uploaded. Media prepared for publishing is publicly accessible. Check the destination's media and thumbnail requirements. The hosted server cannot read a path on your computer. It does not expose `upload_media_from_path`, `create_media_post_from_path` or `create_tiktok_draft_from_path`; those helpers belong to a separately configured local stdio server. A chat attachment works only when the client can transfer its bytes through the supported upload flow or provide a suitable accessible URL. ## Reusable agent skill The [PostOnce skill](https://postonce.to/agent-skills/postonce/SKILL.md) teaches account discovery, media transfer, posting, delivery inspection and automatic crossposting. Use it as workflow guidance according to your client’s supported skill mechanism. Installing a skill adds guidance; it does not authenticate the client or change plan access. ## Errors and recovery * Invalid or revoked credentials: reconnect through the supported client setup. * Missing scope or plan access: follow the returned requirement and update the existing key or plan as appropriate. * Disconnected social account: reconnect it in PostOnce and refresh account discovery. * Invalid media/settings: correct the specific input from the response before retrying. * Uncertain creation result: retain the same `idempotency_key` and identical payload, inspect existing results before retrying, and avoid publishing a second copy. * Partial delivery: inspect each destination and recover the failed destination rather than recreating the post for every target. Revoke manual keys in [Preferences → API keys](https://postonce.to/dashboard/preferences?tab=api-keys). Removing a server configuration or deleting a skill alone does not revoke its credential.