{"openapi":"3.1.0","info":{"title":"Queber API","version":"1.0.0","description":"HTTPS endpoints that run automations in your Queber Desktop app. Use an OAuth app or a personal API token from https://queber.app/account/api. Send an Idempotency-Key with requests that create or change something, and wait for Retry-After before repeating a 429 or 503."},"servers":[{"url":"https://mcp.queber.app"}],"security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:status:read"]}],"paths":{"/actions/account":{"get":{"operationId":"getQueberAccount","summary":"Get Queber account information","description":"Returns the authenticated Queber account and the current AI integration details.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:account:read"]}],"responses":{"200":{"description":"Account and integration details.","content":{"application/json":{"schema":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["user","admin"],"description":"Allowed values: user, admin."},"status":{"type":"string","enum":["active","blocked"],"description":"Allowed values: active, blocked."},"plan":{"type":"string","description":"Queber plan code, for example free or start. Plans are configured by Queber; API access depends on the plan."},"createdAt":{"type":"string","format":"date-time"}},"required":["id"],"additionalProperties":true},"integration":{"type":"object","properties":{"clientId":{"type":"string"},"clientName":{"type":"string"},"clientType":{"type":"string","enum":["official","user","dynamic"],"description":"How the OAuth app was registered. Allowed values: official, user, dynamic."},"createdAt":{"type":"string","format":"date-time"},"scopes":{"type":"array","description":"Scopes granted to this integration. Allowed values: mcp:account:read, mcp:account:write, mcp:status:read, mcp:targets:read, mcp:media:write, mcp:profiles:read, mcp:jobs:read, mcp:jobs:write, mcp:automation:run.","items":{"type":"string","enum":["mcp:account:read","mcp:account:write","mcp:status:read","mcp:targets:read","mcp:media:write","mcp:profiles:read","mcp:jobs:read","mcp:jobs:write","mcp:automation:run"]}}},"required":["clientId","scopes"],"additionalProperties":true}},"required":["account","integration"]},"example":{"account":{"id":"66c1f0a4e2b91d4f7a3c8d21","email":"alex@example.com","role":"user","status":"active","plan":"scale","createdAt":"2026-05-02T11:20:31.000Z"},"integration":{"clientId":"qmc_j-msPGXdZwH80w8wD2FEkrzA3tJWiqKj","clientName":"Swagger UI","clientType":"user","createdAt":"2026-08-11T12:04:48.000Z","scopes":["mcp:account:read","mcp:status:read","mcp:profiles:read","mcp:jobs:read"]}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:account:read"}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}}}}},"/actions/account/logout":{"post":{"operationId":"logoutQueberAccount","summary":"Disconnect this AI integration","description":"Revokes this integration's Queber tokens. Use when the user wants to sign out or disconnect Queber.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:account:write"]}],"responses":{"200":{"description":"Integration disconnected.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"disconnected":{"type":"boolean"},"clientId":{"type":"string"},"revokedAt":{"type":"string","format":"date-time"}},"required":["ok","disconnected","clientId","revokedAt"],"additionalProperties":false},"example":{"ok":true,"disconnected":true,"clientId":"qmc_j-msPGXdZwH80w8wD2FEkrzA3tJWiqKj","revokedAt":"2026-08-12T10:02:11.000Z"}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:account:write"}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}}}}},"/actions/status":{"get":{"operationId":"getQueberStatus","summary":"Get Queber Desktop connection status","description":"Use this before other operations to check whether the user's Queber Desktop app is connected.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:status:read"]}],"responses":{"200":{"description":"Desktop relay status.","content":{"application/json":{"schema":{"type":"object","properties":{"desktopConnected":{"type":"boolean"},"relayConnected":{"type":"boolean","description":"True when the cloud relay has an active Queber Desktop WebSocket session."},"desktopSessionCount":{"type":"integer"},"desktopSessionConflict":{"type":"boolean","description":"True when several Queber Desktop apps without installation ids (older versions) are connected at once; commands are refused until one is closed."},"relayState":{"type":"string","enum":["connected","reconnecting","offline","conflict"],"description":"reconnecting means the desktop dropped without signing out and is expected back; retry after retryAfterSeconds instead of restarting the app. Allowed values: connected, reconnecting, offline, conflict."},"connectedAt":{"type":"string","format":"date-time"},"appVersion":{"type":"string"},"lastPingAt":{"type":"string","format":"date-time"},"lastHeartbeatAt":{"type":"string","format":"date-time","description":"Most recent desktop pong observed by the cloud relay."},"disconnectedAt":{"type":"string","format":"date-time"},"disconnectReason":{"type":"string"},"closeCode":{"type":"integer"},"retryAfterSeconds":{"type":"integer","description":"Suggested wait before retrying while relayState is reconnecting."},"desktops":{"type":"array","description":"Connected Queber Desktop apps. Pass one id as desktopId when several are connected.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"Computer name."},"platform":{"type":"string"},"appVersion":{"type":"string"},"connectedAt":{"type":"string","format":"date-time"},"lastHeartbeatAt":{"type":"string","format":"date-time"},"legacy":{"type":"boolean","description":"True for desktop versions without installation ids."}},"additionalProperties":true}},"recentDisconnects":{"type":"array","description":"Latest relay disconnects for this account, newest first.","items":{"type":"object","additionalProperties":true}},"error":{"type":"string"}},"required":["desktopConnected","desktopSessionCount","desktopSessionConflict"],"additionalProperties":false},"example":{"desktopConnected":true,"relayConnected":true,"relayState":"connected","desktopSessionCount":1,"desktopSessionConflict":false,"connectedAt":"2026-08-12T08:31:20.000Z","appVersion":"1.2.9","lastHeartbeatAt":"2026-08-12T08:31:35.000Z"}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:status:read"}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}}}}},"/actions/capabilities":{"get":{"operationId":"getQueberCapabilities","summary":"Get supported automation capabilities","description":"Use this to learn supported platforms, automation types, browser providers, and desktop commands.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:status:read"]}],"parameters":[{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Supported capabilities.","content":{"application/json":{"schema":{"type":"object","properties":{"capabilities":{"type":"object","properties":{"platforms":{"type":"array","description":"Platforms the product knows about, registered or not. Allowed values: reddit, tiktok, instagram.","items":{"type":"string","enum":["reddit","tiktok","instagram"]}},"automationTypes":{"type":"array","description":"Allowed values: posting, comment, post_read.","items":{"type":"string","enum":["posting","comment","post_read"]}},"registeredAutomations":{"type":"array","description":"Platform and automation type combinations that can actually run.","items":{"type":"object","properties":{"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."}},"additionalProperties":true}},"browserProviders":{"type":"array","description":"Allowed values: local, dolphin, adspower, gologin.","items":{"type":"string","enum":["local","dolphin","adspower","gologin"]}},"commands":{"type":"array","description":"Desktop relay commands behind these actions.","items":{"type":"string"}}},"additionalProperties":true}},"required":["capabilities"]},"example":{"capabilities":{"platforms":["reddit","tiktok","instagram"],"automationTypes":["posting","comment","post_read"],"registeredAutomations":[{"platform":"reddit","automationType":"posting"},{"platform":"reddit","automationType":"post_read"}],"browserProviders":["local","dolphin","adspower","gologin"],"commands":["app.status","app.capabilities","target.analyze","media.import","profiles.list","profiles.get","profiles.open","profiles.close","integrations.status","jobs.list","jobs.get","jobs.logs","jobs.comments","jobs.progress","jobs.run","jobs.schedule","jobs.cancel","jobs.archive","jobs.unarchive","jobs.delete","jobs.retry","jobs.update"]}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:status:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/profiles":{"get":{"operationId":"listProfiles","summary":"List Queber browser profiles","description":"Use this to list browser profiles available in the user's connected Queber Desktop app.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:profiles:read"]}],"parameters":[{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Browser profiles.","content":{"application/json":{"schema":{"type":"object","properties":{"profiles":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider that owns the profile. Allowed values: local, dolphin, adspower, gologin."},"status":{"type":"string","enum":["idle","running","error"],"description":"Current local profile state. Allowed values: idle, running, error."},"runningSource":{"type":"string","enum":["job","manual"],"description":"Set while the profile runs: started by a job or by the user. Allowed values: job, manual."},"externalId":{"type":"string","description":"Provider profile id for imported profiles."},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"alsoOnDesktops":{"type":"array","description":"Other connected desktop apps that imported the same provider browser profile. Running it on two computers at once can clash.","items":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true}},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"total":{"type":"integer"},"unavailableDesktops":{"type":"array","description":"Connected desktop apps that could not answer, when the list merges several of them.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}},"required":["profiles","total"]},"example":{"profiles":[{"id":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","name":"Reddit main","provider":"local","status":"running","runningSource":"manual","createdAt":"2026-07-28T09:12:44.000Z","lastUsedAt":"2026-08-12T08:55:10.000Z"},{"id":"7d2e5f80-1a3b-4c6d-8e9f-0a1b2c3d4e5f","name":"Dolphin backup","provider":"dolphin","status":"idle","externalId":"1284471","createdAt":"2026-06-14T15:02:19.000Z"}],"total":2}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:profiles:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/profiles/{profileId}":{"get":{"operationId":"getProfile","summary":"Get one Queber browser profile","description":"Use this when details for a specific browser profile are needed.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:profiles:read"]}],"parameters":[{"name":"profileId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber browser profile id.","example":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Browser profile.","content":{"application/json":{"schema":{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider that owns the profile. Allowed values: local, dolphin, adspower, gologin."},"status":{"type":"string","enum":["idle","running","error"],"description":"Current local profile state. Allowed values: idle, running, error."},"runningSource":{"type":"string","enum":["job","manual"],"description":"Set while the profile runs: started by a job or by the user. Allowed values: job, manual."},"externalId":{"type":"string","description":"Provider profile id for imported profiles."},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"alsoOnDesktops":{"type":"array","description":"Other connected desktop apps that imported the same provider browser profile. Running it on two computers at once can clash.","items":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true}},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"required":["profile"]},"example":{"profile":{"id":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","name":"Reddit main","provider":"local","status":"running","runningSource":"manual","createdAt":"2026-07-28T09:12:44.000Z","lastUsedAt":"2026-08-12T08:55:10.000Z"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:profiles:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Profile not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_selection_required","message":"Profile 3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607 exists on several Queber Desktop apps, usually because app data was copied to another computer. Repeat the request with desktopId set to one of error.desktops.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/profiles/{profileId}/open":{"post":{"operationId":"openProfile","summary":"Open a browser profile","description":"Opens a browser profile through the user's Queber Desktop app. This changes local desktop state.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:profiles:read","mcp:automation:run"]}],"parameters":[{"name":"profileId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber browser profile id.","example":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Opened profile.","content":{"application/json":{"schema":{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider that owns the profile. Allowed values: local, dolphin, adspower, gologin."},"status":{"type":"string","enum":["idle","running","error"],"description":"Current local profile state. Allowed values: idle, running, error."},"runningSource":{"type":"string","enum":["job","manual"],"description":"Set while the profile runs: started by a job or by the user. Allowed values: job, manual."},"externalId":{"type":"string","description":"Provider profile id for imported profiles."},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"alsoOnDesktops":{"type":"array","description":"Other connected desktop apps that imported the same provider browser profile. Running it on two computers at once can clash.","items":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true}},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"required":["profile"]},"example":{"profile":{"id":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","name":"Reddit main","provider":"local","status":"running","runningSource":"manual","createdAt":"2026-07-28T09:12:44.000Z","lastUsedAt":"2026-08-12T08:55:10.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:profiles:read mcp:automation:run"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Profile not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Dolphin Anty is not running. Please start it."}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/profiles/{profileId}/close":{"post":{"operationId":"closeProfile","summary":"Close a browser profile","description":"Closes all local sessions for a browser profile. This changes local desktop state.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:profiles:read","mcp:automation:run"]}],"parameters":[{"name":"profileId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber browser profile id.","example":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Closed profile.","content":{"application/json":{"schema":{"type":"object","properties":{"profile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"provider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider that owns the profile. Allowed values: local, dolphin, adspower, gologin."},"status":{"type":"string","enum":["idle","running","error"],"description":"Current local profile state. Allowed values: idle, running, error."},"runningSource":{"type":"string","enum":["job","manual"],"description":"Set while the profile runs: started by a job or by the user. Allowed values: job, manual."},"externalId":{"type":"string","description":"Provider profile id for imported profiles."},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"alsoOnDesktops":{"type":"array","description":"Other connected desktop apps that imported the same provider browser profile. Running it on two computers at once can clash.","items":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true}},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}},"additionalProperties":true}},"required":["profile"]},"example":{"profile":{"id":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","name":"Reddit main","provider":"local","status":"idle","createdAt":"2026-07-28T09:12:44.000Z","lastUsedAt":"2026-08-12T08:55:10.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:profiles:read mcp:automation:run"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Profile not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Dolphin Anty is not running. Please start it."}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/integrations/status":{"get":{"operationId":"getIntegrationsStatus","summary":"Get browser provider integration status","description":"Use this to check local provider integrations such as Dolphin, AdsPower, GoLogin, and local profiles.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:status:read"]}],"parameters":[{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Integration status.","content":{"application/json":{"schema":{"type":"object","properties":{"integrations":{"type":"object","additionalProperties":true}},"required":["integrations"]},"example":{"integrations":{"local":{"configured":true,"running":true,"authenticated":true},"dolphin":{"configured":true,"running":true,"authenticated":true},"adspower":{"configured":false,"running":false,"authenticated":false,"localApiUrl":"http://local.adspower.net:50325"},"gologin":{"configured":true,"running":false,"authenticated":true}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:status:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/subreddit/analyze":{"post":{"operationId":"analyzeSubreddit","summary":"Analyze an automation target","description":"Analyze a target before creating a job. For Reddit it returns subreddit metadata, flairs, and content types. Use one allowedJobPostTypes value as platformData.reddit.posting.type.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:targets:read"]}],"parameters":[{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"Optional profile id for profile-aware analysis."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"target":{"type":"string","description":"Platform target, for example r/anime for Reddit posting."},"desktopId":{"type":"string","description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"required":["platform","automationType","target"],"additionalProperties":false},"examples":{"subreddit":{"summary":"Subreddit target","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","target":"r/webdev"}},"userProfile":{"summary":"User target, no metadata analysis","value":{"platform":"reddit","automationType":"posting","target":"u/spez"}}}}}},"responses":{"200":{"description":"Target analysis result.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"target":{"type":"string"},"targetType":{"type":"string","description":"Target kind as the platform names it. For Reddit: r for a subreddit, u for a user."},"analysisAvailable":{"type":"boolean"},"message":{"type":"string"},"allowedPostTypes":{"type":"array","description":"Raw content types the target accepts. Allowed values: text, link, image, video.","items":{"type":"string","enum":["text","link","image","video"]}},"allowedJobPostTypes":{"type":"array","description":"Values accepted as platformData.reddit.posting.type for this target. Allowed values: text, image, video, link, media.","items":{"type":"string","enum":["text","image","video","link","media"]}},"flairRequired":{"type":"boolean"},"data":{"type":"object","description":"Target metadata. For Reddit: about and postMetadata.","properties":{"about":{"type":"object","properties":{"display_name":{"type":"string","description":"Subreddit name without the r/ prefix."},"title":{"type":["string","null"]},"over18":{"type":"boolean"},"submission_type":{"type":"string","enum":["any","self","link"],"description":"What the subreddit accepts. Allowed values: any, self, link."},"allow_images":{"type":"boolean"},"allow_videos":{"type":"boolean"},"allow_galleries":{"type":"boolean"},"link_flair_enabled":{"type":"boolean"},"user_can_flair_in_sr":{"type":"boolean"}},"additionalProperties":true},"postMetadata":{"type":"object","properties":{"postingTypes":{"type":"array","description":"Content types the subreddit accepts. Allowed values: text, link, image, video.","items":{"type":"string","enum":["text","link","image","video"]}},"flairRequired":{"type":"boolean"},"flairsAllowed":{"type":"boolean"},"flairButtonVisible":{"type":"boolean"},"flairs":{"type":"array","description":"Post flairs. Send id as platformData.reddit.posting.flairId, or text as flairText only when it is unique.","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"}},"additionalProperties":true}},"tags":{"type":"array","description":"Post tag availability for this subreddit.","items":{"type":"object","properties":{"id":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"],"description":"Allowed values: nsfw, spoiler, brand_affiliate."},"label":{"type":"string"},"available":{"type":"boolean"},"checked":{"type":"boolean"},"disabled":{"type":"boolean"}},"additionalProperties":true}}},"additionalProperties":true}},"additionalProperties":true}},"required":["ok","platform","automationType","target","analysisAvailable"],"additionalProperties":true},"example":{"ok":true,"platform":"reddit","automationType":"posting","target":"r/webdev","targetType":"r","analysisAvailable":true,"allowedPostTypes":["text","link","image"],"allowedJobPostTypes":["text","link","image"],"flairRequired":true,"data":{"about":{"display_name":"webdev","title":"Web Development","over18":false,"submission_type":"any","allow_images":true,"allow_videos":false,"allow_galleries":true,"link_flair_enabled":true,"user_can_flair_in_sr":true},"postMetadata":{"postingTypes":["text","link","image"],"flairRequired":true,"flairsAllowed":true,"flairButtonVisible":true,"flairs":[{"id":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","text":"Showoff Saturday"},{"id":"7b1d9f60-2b44-11ee-8a3c-0e2b1d3c4a55","text":"Question"}],"tags":[{"id":"spoiler","label":"Spoiler","available":true,"checked":false,"disabled":false},{"id":"nsfw","label":"NSFW","available":true,"checked":false,"disabled":false}]}}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:targets:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"429":{"description":"Too many requests. reddit_rate_limited: Reddit is limiting metadata requests. rate_limited: Queber is limiting requests. Wait for Retry-After (also error.retryAfterSeconds), then repeat the request.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"reddit_rate_limited","message":"Reddit target analysis failed: Reddit is rate limiting requests. Try again in 30 seconds","retryable":true,"retryAfterSeconds":30}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Reddit target analysis failed: fetch failed"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/reddit/comments/check":{"post":{"operationId":"checkRedditCommentTarget","summary":"Check where a Reddit comment goes","description":"Opens the post with the profile, free and outside the queue: whether it takes comments, what media the comment box accepts, and up to 300 comments with ids to pass as replyToCommentId. Takes up to 3 minutes when the profile has to start.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:targets:read"]}],"parameters":[{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"Profile that will comment: what Reddit shows depends on the account."},"link":{"type":"string","description":"The post, or a link to the comment to answer."},"replyToCommentId":{"type":"string","description":"Optional comment id to check, as in job content."},"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"required":["profileId","link"],"additionalProperties":false},"examples":{"comment":{"summary":"Check the comment to answer and its thread","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","link":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohd7k2m/"}},"post":{"summary":"List the post's comments to pick from","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","link":"https://www.reddit.com/r/webdev/comments/1abc234/how_we_run_reddit_posting/"}}}}}},"responses":{"200":{"description":"What a comment job would find on the post.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"target":{"type":"string","description":"The post address."},"message":{"type":"string","description":"Same as check.blocked.message when the account cannot comment there."},"check":{"type":"object","properties":{"post":{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"},"title":{"type":"string"},"author":{"type":"string"},"comments":{"type":["integer","null"]},"nsfw":{"type":"boolean"}},"required":["url"],"additionalProperties":true},"blocked":{"type":["object","null"],"description":"Why the account cannot comment there; null when it can. A target_* code is about the comment to answer: pick another one or comment on the post. Any other code is about the post or the account.","properties":{"code":{"type":"string","enum":["post_not_found","community_unavailable","mature_content","post_removed","post_archived","post_locked","comments_closed","captcha_required","target_not_found","target_removed","target_locked","media_not_allowed"],"description":"Why commenting there is not possible. Allowed values: post_not_found, community_unavailable, mature_content, post_removed, post_archived, post_locked, comments_closed, captcha_required, target_not_found, target_removed, target_locked, media_not_allowed."},"message":{"type":"string","description":"Reddit's own words where it shows any."}},"required":["code","message"],"additionalProperties":false},"media":{"type":["object","null"],"description":"What the comment box takes in this community; null when the page shows no comment box.","properties":{"images":{"type":"boolean"},"animatedImages":{"type":"boolean","description":"GIF files."},"videos":{"type":"boolean"},"maxMedia":{"type":"integer"}},"additionalProperties":true},"account":{"type":["string","null"],"description":"The Reddit account the profile is signed in to."},"target":{"type":"object","properties":{"id":{"type":"string","description":"Reddit comment id, as in its permalink (.../comment/<id>/)."},"parentId":{"type":["string","null"],"description":"Id of the comment it answers; null for a comment on the post itself."},"depth":{"type":"integer","description":"0 for a comment on the post, 1 for a reply to it, and so on."},"author":{"type":["string","null"],"description":"Null when the account is gone."},"isOp":{"type":"boolean","description":"The post's author wrote it."},"body":{"type":"string","description":"Text as shown, paragraphs separated by a blank line; empty for deleted and removed comments; at most 10,000 characters."},"score":{"type":["integer","null"],"description":"Null when the community hides comment scores for now."},"awards":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":"string","format":"date-time","description":"When the author last edited it; only on edited comments."},"permalink":{"type":"string"},"collapsed":{"type":"boolean","description":"Reddit collapses it in the thread, for example for a low score."},"state":{"type":"string","enum":["ok","deleted","removed"],"description":"ok: a comment with its author. deleted: the author or the account deleted it. removed: Reddit or the moderators took it down. Allowed values: ok, deleted, removed."},"moreReplies":{"type":["integer","null"],"description":"Only when replies under it were not loaded: their number as Reddit shows it (\"4 more replies\"), null when Reddit shows no number (a deep thread continues on its own page)."}},"required":["id","parentId","depth","author","isOp","body","score","awards","collapsed","state"],"additionalProperties":true,"description":"The comment a comment link or replyToCommentId names."},"thread":{"type":["object","null"],"description":"Up to 300 comments of the post, or the thread of a linked comment, in page order; pass one id as replyToCommentId.","properties":{"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"The order the comments were loaded in. Allowed values: best, top, new, old, controversial, qa."},"total":{"type":["integer","null"],"description":"Comments Reddit counts on the post, deleted and hidden ones included."},"loaded":{"type":"integer","description":"Comments the read loaded; getJobComments returns them page by page."},"complete":{"type":"boolean","description":"Every comment Reddit offered on the page was loaded."},"stoppedBy":{"type":"string","enum":["limit","run_limit","time"],"description":"Why the thread holds fewer comments than the post has. limit: the per-post limit. run_limit: the run's 5,000-comment budget. time: loading took longer than the 2 minutes a post gets. Allowed values: limit, run_limit, time."},"comments":{"type":"array","description":"Only in the desktop app and its exports; getJob and listJobs leave them out, getJobComments pages them.","items":{"type":"object","properties":{"id":{"type":"string","description":"Reddit comment id, as in its permalink (.../comment/<id>/)."},"parentId":{"type":["string","null"],"description":"Id of the comment it answers; null for a comment on the post itself."},"depth":{"type":"integer","description":"0 for a comment on the post, 1 for a reply to it, and so on."},"author":{"type":["string","null"],"description":"Null when the account is gone."},"isOp":{"type":"boolean","description":"The post's author wrote it."},"body":{"type":"string","description":"Text as shown, paragraphs separated by a blank line; empty for deleted and removed comments; at most 10,000 characters."},"score":{"type":["integer","null"],"description":"Null when the community hides comment scores for now."},"awards":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":"string","format":"date-time","description":"When the author last edited it; only on edited comments."},"permalink":{"type":"string"},"collapsed":{"type":"boolean","description":"Reddit collapses it in the thread, for example for a low score."},"state":{"type":"string","enum":["ok","deleted","removed"],"description":"ok: a comment with its author. deleted: the author or the account deleted it. removed: Reddit or the moderators took it down. Allowed values: ok, deleted, removed."},"moreReplies":{"type":["integer","null"],"description":"Only when replies under it were not loaded: their number as Reddit shows it (\"4 more replies\"), null when Reddit shows no number (a deep thread continues on its own page)."}},"required":["id","parentId","depth","author","isOp","body","score","awards","collapsed","state"],"additionalProperties":true}}},"required":["sort","total","loaded","complete"],"additionalProperties":true},"checkedAt":{"type":"string","format":"date-time"}},"required":["post","blocked","media","account","thread","checkedAt"],"additionalProperties":true}},"required":["ok","check"],"additionalProperties":true},"example":{"ok":true,"target":"https://www.reddit.com/r/webdev/comments/1abc234/","check":{"post":{"url":"https://www.reddit.com/r/webdev/comments/1abc234/","postId":"1abc234","community":"r/webdev","title":"How we run Reddit posting from real browser profiles","author":"queber_team","comments":2,"nsfw":false},"blocked":null,"media":{"images":true,"animatedImages":true,"videos":false,"maxMedia":1},"account":"queber_team","target":{"id":"ohd7k2m","parentId":null,"depth":0,"author":"quiet_reader","isOp":false,"body":"Does it keep the profile logged in?","score":4,"awards":0,"createdAt":"2026-08-12T09:40:00.000Z","collapsed":false,"state":"ok","permalink":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohd7k2m/"},"thread":{"sort":"best","total":2,"loaded":2,"complete":true,"comments":[{"id":"ohd7k2m","parentId":null,"depth":0,"author":"quiet_reader","isOp":false,"body":"Does it keep the profile logged in?","score":4,"awards":0,"createdAt":"2026-08-12T09:40:00.000Z","collapsed":false,"state":"ok","permalink":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohd7k2m/"},{"id":"ohd8a1b","parentId":"ohd7k2m","depth":1,"author":"queber_team","isOp":true,"body":"Yes, each profile keeps its own session.","score":2,"awards":0,"createdAt":"2026-08-12T09:52:00.000Z","collapsed":false,"state":"ok","permalink":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohd8a1b/"}]},"checkedAt":"2026-08-12T10:01:07.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:targets:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/media/import":{"post":{"operationId":"importMedia","summary":"Import media for a job","description":"Imports an image or video into Queber Desktop and returns a media item for job creation. Prefer an attached file, otherwise sourceUrl, dataUrl, dataBase64, or desktopPath. Sandbox paths cannot be read.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:media:write","mcp:automation:run"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceUrl":{"type":"string","description":"Public http(s) URL to download the media from."},"openaiFileIdRefs":{"type":"array","description":"File references sent by OpenAI-style action clients for an attached image or video.","items":{"type":"string"}},"fileName":{"type":"string","description":"Optional. Inferred from the attachment, URL, or content type."},"mediaType":{"type":"string","enum":["image","video"],"description":"Optional. Inferred from the content type or extension. Allowed values: image, video."},"mimeType":{"type":"string","description":"Optional content type such as image/png."},"dataBase64":{"type":"string","description":"Raw base64 file bytes."},"dataUrl":{"type":"string","description":"Data URL such as data:image/png;base64,..."},"desktopPath":{"type":"string","description":"Absolute path to a file on the Queber Desktop machine."},"profileId":{"type":"string","description":"Profile the media is for. With several desktop apps connected it picks the computer the file is saved on."},"desktopId":{"type":"string","description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"sourceUrl":{"summary":"Public URL (preferred)","value":{"sourceUrl":"https://cdn.example.com/queber/launch-promo.png","fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png"}},"dataUrl":{"summary":"Inline data URL","value":{"fileName":"launch-promo.png","mediaType":"image","dataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="}},"dataBase64":{"summary":"Raw base64 bytes","value":{"fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png","dataBase64":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="}},"desktopPath":{"summary":"File already on the desktop machine","value":{"mediaType":"image","desktopPath":"C:\\Users\\alex\\Pictures\\launch-promo.png"}},"video":{"summary":"Video from a public URL","value":{"sourceUrl":"https://cdn.example.com/queber/launch-demo.mp4","fileName":"launch-demo.mp4","mediaType":"video","mimeType":"video/mp4"}}}}}},"responses":{"200":{"description":"Imported media.","content":{"application/json":{"schema":{"type":"object","properties":{"media":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false},"path":{"type":"string"},"bytes":{"type":"integer"},"source":{"type":"string","enum":["sourceUrl","dataUrl","dataBase64","desktopPath"],"description":"Where the imported bytes came from. Allowed values: sourceUrl, dataUrl, dataBase64, desktopPath."}},"required":["media","path"],"additionalProperties":true},"example":{"media":{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"},"path":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","bytes":284117,"source":"sourceUrl"}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:media:write mcp:automation:run"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Media download returned an empty file"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/debug/upload-echo":{"post":{"operationId":"debugUploadEcho","summary":"Echo received upload input","description":"Diagnostic action. Send the same input as importMedia to check what Queber received: an attachment, a public download link, a local sandbox path, or inline bytes. Nothing is imported.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:media:write"]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"sourceUrl":{"type":"string","description":"Public http(s) URL to download the media from."},"openaiFileIdRefs":{"type":"array","description":"File references sent by OpenAI-style action clients for an attached image or video.","items":{"type":"string"}},"fileName":{"type":"string","description":"Optional. Inferred from the attachment, URL, or content type."},"mediaType":{"type":"string","enum":["image","video"],"description":"Optional. Inferred from the content type or extension. Allowed values: image, video."},"mimeType":{"type":"string","description":"Optional content type such as image/png."},"dataBase64":{"type":"string","description":"Raw base64 file bytes."},"dataUrl":{"type":"string","description":"Data URL such as data:image/png;base64,..."},"desktopPath":{"type":"string","description":"Absolute path to a file on the Queber Desktop machine."},"profileId":{"type":"string","description":"Profile the media is for. With several desktop apps connected it picks the computer the file is saved on."},"desktopId":{"type":"string","description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"sourceUrl":{"summary":"Public URL (preferred)","value":{"sourceUrl":"https://cdn.example.com/queber/launch-promo.png","fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png"}},"dataUrl":{"summary":"Inline data URL","value":{"fileName":"launch-promo.png","mediaType":"image","dataUrl":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="}},"dataBase64":{"summary":"Raw base64 bytes","value":{"fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png","dataBase64":"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8DwHwAFAAH/q842iQAAAABJRU5ErkJggg=="}},"desktopPath":{"summary":"File already on the desktop machine","value":{"mediaType":"image","desktopPath":"C:\\Users\\alex\\Pictures\\launch-promo.png"}},"video":{"summary":"Video from a public URL","value":{"sourceUrl":"https://cdn.example.com/queber/launch-demo.mp4","fileName":"launch-demo.mp4","mediaType":"video","mimeType":"video/mp4"}}}}}},"responses":{"200":{"description":"Echo of the upload input received by Queber, and how it would be imported.","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"object","description":"Echo of the request, with inline bytes replaced by their length.","additionalProperties":true},"attachmentReceived":{"type":"boolean"},"fileRefs":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"id":{"type":"string"},"mime_type":{"type":"string"},"download_link":{"type":"string"}},"additionalProperties":true}},"fileRefCount":{"type":"integer"},"hasDownloadLinks":{"type":"boolean"},"publicDownloadLinks":{"type":"array","items":{"type":"string"}},"localPathDownloadLinks":{"type":"array","description":"Sandbox or local paths Queber cannot download.","items":{"type":"string"}},"importable":{"type":"boolean","description":"True when importMedia would accept this input."},"mediaSource":{"type":"string","enum":["sourceUrl","dataUrl","dataBase64","desktopPath"],"description":"Source importMedia would use for this input. Allowed values: sourceUrl, dataUrl, dataBase64, desktopPath."},"normalizedMedia":{"type":"object","description":"Media payload importMedia would send to the desktop app.","properties":{"fileName":{"type":"string"},"mediaType":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"mimeType":{"type":"string"},"fileId":{"type":"string"},"sourceUrl":{"type":"string"},"desktopPath":{"type":"string"},"inlineDataCharacters":{"type":"integer"}},"additionalProperties":false},"importError":{"type":"string"}},"required":["received","attachmentReceived","fileRefs","fileRefCount","hasDownloadLinks","publicDownloadLinks","localPathDownloadLinks","importable"],"additionalProperties":false},"example":{"received":{"sourceUrl":"https://cdn.example.com/queber/launch-promo.png","fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png"},"attachmentReceived":false,"fileRefs":[],"fileRefCount":0,"hasDownloadLinks":true,"publicDownloadLinks":["https://cdn.example.com/queber/launch-promo.png"],"localPathDownloadLinks":[],"importable":true,"mediaSource":"sourceUrl","normalizedMedia":{"fileName":"launch-promo.png","mediaType":"image","mimeType":"image/png","sourceUrl":"https://cdn.example.com/queber/launch-promo.png"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:media:write"}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}}}}},"/actions/jobs":{"get":{"operationId":"listJobs","summary":"List Queber automation jobs","description":"Lists jobs page by page, without logs (getJobLogs: /actions/jobs/{jobId}/logs) or post read comments (getJobComments). A page holds up to limit jobs, 100 by default, 500 at most: while nextCursor is not null, call again with it as cursor and the same filters. Archived jobs need archived=true.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:read"]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500},"description":"Jobs per page, 100 by default and 500 at most. A page can hold fewer jobs while more remain; nextCursor tells whether there are more.","example":100},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"nextCursor of the previous page. Send it with the same filters and sort to read the next page; leave it out for the first page.","example":"eyJ2IjoxLCJxIjoiTFRXdlNuZzNjcUVyIiwiZCI6eyI2YjFmMmMzZC00ZTVmLTRhNmItOGM3ZC05ZTBmMWEyYjNjNGQiOnsiYyI6ImV5SnpkR0Z5ZENJNklqSXdNall0TURndE1USlVNRGs2TkRBNk5UVXVNREF3V2lJc0ltbGtJam9pT1dNNFlqZGhOalV0TkRNeU1TMDBaakJsTFRsa09HTXROMkkyWVRWbU5HVXpaREl4SW4wIn19fQ"},{"name":"status","in":"query","required":false,"schema":{"type":"string"},"description":"Only jobs in these statuses, comma-separated, for example failed,cancelled. Every status by default. Allowed values: pending, running, paused, completed, failed, cancelled.","example":"failed,cancelled"},{"name":"archived","in":"query","required":false,"schema":{"type":"boolean"},"description":"true lists only archived jobs. Archived jobs are left out by default.","example":true},{"name":"startFrom","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Only jobs that start at or after this ISO datetime. A job starts at its scheduledAt, or at createdAt when it was created to run now.","example":"2026-08-10T00:00:00.000Z"},{"name":"startBefore","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Only jobs that start before this ISO datetime.","example":"2026-08-17T00:00:00.000Z"},{"name":"profileId","in":"query","required":false,"schema":{"type":"string"},"description":"Only jobs of these Queber browser profiles, comma-separated profile ids.","example":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607"},{"name":"platform","in":"query","required":false,"schema":{"type":"string"},"description":"Only jobs of these platforms, comma-separated. Allowed values: reddit, tiktok, instagram.","example":"reddit"},{"name":"automationType","in":"query","required":false,"schema":{"type":"string"},"description":"Only jobs of these automations, comma-separated, for example post_read. Allowed values: posting, comment, post_read.","example":"post_read"},{"name":"source","in":"query","required":false,"schema":{"type":"string"},"description":"Only jobs created from these places, comma-separated: app (the desktop app, also jobs from before sources existed), api, mcp. Allowed values: app, api, mcp.","example":"api,mcp"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["start:desc","start:asc","profile:desc","profile:asc","status:desc","status:asc"],"description":"Order of the list by start time, profile name, or status. Default start:desc, the latest start first. Allowed values: start:desc, start:asc, profile:desc, profile:asc, status:desc, status:asc."},"description":"Order of the list by start time, profile name, or status. Default start:desc, the latest start first. Allowed values: start:desc, start:asc, profile:desc, profile:asc, status:desc, status:asc.","example":"start:desc"},{"name":"search","in":"query","required":false,"schema":{"type":"string"},"description":"Case-insensitive text matched against the job id, label, profile name, and target.","example":"r/webdev"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id from /actions/status. Needed only when several desktop apps are connected and the request names no profile or job.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"One page of automation jobs.","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, cleared when the job is queued again. A post read keeps its results in reddit.post_read, a comment its permalink in reddit.comment; poll getJob until the job completes.","properties":{"reddit":{"type":"object","properties":{"post_read":{"type":"object","description":"Result of a Reddit post read: one item per link, in the order of the links.","properties":{"items":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"The link as the job stores it."},"postId":{"type":"string","description":"Reddit post id. A share link gets it from the page; missing when the page did not open."},"status":{"type":"string","enum":["ok","removed","not_found","failed"],"description":"ok: the post was read. removed: Reddit shows a removal banner. not_found: Reddit has no such post. failed: the link could not be read; see error. Allowed values: ok, removed, not_found, failed."},"readAs":{"type":"string","enum":["author","other"],"description":"author when the profile that ran the read wrote the post. Reddit shows views, shares, reposts, the countries with the most views, and removal banners of own posts only to the author. Allowed values: author, other."},"permalink":{"type":"string"},"community":{"type":"string","description":"r/<name>, or u/<name> for a profile post."},"title":{"type":"string"},"author":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"score":{"type":["integer","null"]},"upvoteRatio":{"type":["number","null"],"description":"From 0 to 1."},"comments":{"type":["integer","null"]},"views":{"type":["number","null"],"description":"Only on the profile's own posts, rounded as Reddit shows them (5.2K is 5200); null on other posts. Each read of an own post adds one view on Reddit."},"awards":{"type":["integer","null"],"description":"Awards the post received. Reddit leaves the count off removed posts."},"shares":{"type":["integer","null"],"description":"Times the post was shared. Only on the profile's own live posts, from Reddit's stats page of the post; null otherwise."},"reposts":{"type":["integer","null"],"description":"Times the post was reposted to other communities. Only on the profile's own live posts; null otherwise."},"topCountries":{"type":["array","null"],"description":"The countries with the most views, then the rest of the world, as Reddit's stats page lists them. Only on the profile's own live posts; empty when Reddit lists none yet; null otherwise. Each read of an own post adds a view from the profile's own country.","items":{"type":"object","properties":{"country":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 code from Reddit's flag; null for the rest of the world."},"name":{"type":"string","description":"The name as Reddit wrote it, in the account's language."},"percent":{"type":"number","description":"Share of the views, 0 to 100."}},"required":["country","name","percent"],"additionalProperties":true}},"authorRank":{"type":["integer","null"],"description":"The post's place among all the author's posts when Reddit names one (\"This is your #1 post of all time\"); null when it names none. Only when the profile's own post stats were read."},"locked":{"type":"boolean"},"nsfw":{"type":"boolean"},"removalMessage":{"type":"string","description":"Only on removed: the banner text exactly as Reddit shows it, in the account's language."},"error":{"type":"string","description":"Only on failed: why the link could not be read."},"errorCode":{"type":"string","enum":["mature_content_hidden"],"description":"Only on failed, when the reason is known. mature_content_hidden: Reddit hides the post until the account confirms it is over 18. Allowed values: mature_content_hidden."},"warnings":{"type":"array","description":"Values Reddit did not show as an exact number. A null value always has a warning.","items":{"type":"object","properties":{"field":{"type":"string","enum":["score","upvoteRatio","comments","views","awards","shares","reposts","topCountries"],"description":"The value the warning is about. Allowed values: score, upvoteRatio, comments, views, awards, shares, reposts, topCountries."},"code":{"type":"string","enum":["author_only","not_shown","rounded"],"description":"author_only: Reddit shows it only to the post author. not_shown: Reddit did not show it. rounded: the number is Reddit's rounded value. Allowed values: author_only, not_shown, rounded."},"message":{"type":"string"}},"required":["field","code","message"],"additionalProperties":true}},"commentThread":{"type":"object","description":"Only when the read asked for comments and the post page showed them.","properties":{"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"The order the comments were loaded in. Allowed values: best, top, new, old, controversial, qa."},"total":{"type":["integer","null"],"description":"Comments Reddit counts on the post, deleted and hidden ones included."},"loaded":{"type":"integer","description":"Comments the read loaded; getJobComments returns them page by page."},"complete":{"type":"boolean","description":"Every comment Reddit offered on the page was loaded."},"stoppedBy":{"type":"string","enum":["limit","run_limit","time"],"description":"Why the thread holds fewer comments than the post has. limit: the per-post limit. run_limit: the run's 5,000-comment budget. time: loading took longer than the 2 minutes a post gets. Allowed values: limit, run_limit, time."},"comments":{"type":"array","description":"Only in the desktop app and its exports; getJob and listJobs leave them out, getJobComments pages them.","items":{"type":"object","properties":{"id":{"type":"string","description":"Reddit comment id, as in its permalink (.../comment/<id>/)."},"parentId":{"type":["string","null"],"description":"Id of the comment it answers; null for a comment on the post itself."},"depth":{"type":"integer","description":"0 for a comment on the post, 1 for a reply to it, and so on."},"author":{"type":["string","null"],"description":"Null when the account is gone."},"isOp":{"type":"boolean","description":"The post's author wrote it."},"body":{"type":"string","description":"Text as shown, paragraphs separated by a blank line; empty for deleted and removed comments; at most 10,000 characters."},"score":{"type":["integer","null"],"description":"Null when the community hides comment scores for now."},"awards":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":"string","format":"date-time","description":"When the author last edited it; only on edited comments."},"permalink":{"type":"string"},"collapsed":{"type":"boolean","description":"Reddit collapses it in the thread, for example for a low score."},"state":{"type":"string","enum":["ok","deleted","removed"],"description":"ok: a comment with its author. deleted: the author or the account deleted it. removed: Reddit or the moderators took it down. Allowed values: ok, deleted, removed."},"moreReplies":{"type":["integer","null"],"description":"Only when replies under it were not loaded: their number as Reddit shows it (\"4 more replies\"), null when Reddit shows no number (a deep thread continues on its own page)."}},"required":["id","parentId","depth","author","isOp","body","score","awards","collapsed","state"],"additionalProperties":true}}},"required":["sort","total","loaded","complete"],"additionalProperties":true},"checkedAt":{"type":"string","format":"date-time"}},"required":["url","status","warnings","checkedAt"],"additionalProperties":true}},"summary":{"type":"object","description":"Counts over items. read counts links read to a result, removed and not found included; the run is charged only when read is above 0.","properties":{"total":{"type":"integer"},"read":{"type":"integer"},"removed":{"type":"integer"},"notFound":{"type":"integer"},"failed":{"type":"integer"}},"required":["total","read","removed","notFound","failed"],"additionalProperties":true}},"required":["items","summary"],"additionalProperties":true},"comment":{"type":"object","description":"Result of a Reddit comment; resultUrl holds the same permalink.","properties":{"commentId":{"type":"string","description":"Base-36 id of the new comment."},"permalink":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"},"parentId":{"type":["string","null"],"description":"The comment answered; null for a comment on the post."},"repliedTo":{"type":"object","properties":{"commentId":{"type":"string"},"author":{"type":["string","null"]}},"additionalProperties":true},"alreadyPosted":{"type":"boolean","description":"The account's same comment was already there, left by an earlier run of this job that stopped after sending it; nothing was sent again and nothing is charged."},"postedAt":{"type":"string","format":"date-time"}},"required":["commentId","permalink","parentId","postedAt"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"total":{"type":"integer","description":"Jobs that match the filters on all pages together."},"unavailableDesktops":{"type":"array","description":"Connected desktop apps that could not answer, when the list merges several of them.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}},"nextCursor":{"type":["string","null"],"description":"Send as cursor, with the same filters and sort, to read the next page. null on the last page."}},"required":["jobs","total","nextCursor"]},"example":{"jobs":[{"id":"b5a49382-71cd-4e0f-9a2b-6c7d8e9f0a1b","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"pending","source":"api","pause":"10-20","attempts":0,"platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","type":"image","body":"Screenshot of the new queue screen.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","tags":["spoiler"]}}},"createdAt":"2026-08-12T09:40:55.000Z","scheduledAt":"2026-08-13T07:14:00.000Z","requestedScheduledAt":"2026-08-13T07:00:00.000Z","startMovedByPause":true},{"id":"e2d4f6a8-1b3c-4d5e-8f70-9a1b2c3d4e5f","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"post_read","status":"completed","source":"api","pause":"off","attempts":1,"platformData":{"reddit":{"post_read":{"links":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","community":"r/SideProject"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","community":"r/webdev"},{"url":"https://www.reddit.com/comments/1abe456/","postId":"1abe456"},{"url":"https://www.reddit.com/u/queber_demo/comments/1abf567/","postId":"1abf567","community":"u/queber_demo"},{"url":"https://www.reddit.com/r/photography/s/aB3dE5fG7h","community":"r/photography"}]}}},"createdAt":"2026-08-12T10:05:00.000Z","startedAt":"2026-08-12T10:05:01.000Z","completedAt":"2026-08-12T10:06:14.000Z","resultDescription":"Read 4 of 5 posts: 1 removed, 1 not found, 1 failed","resultData":{"reddit":{"post_read":{"items":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","status":"ok","readAs":"author","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","community":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","author":"queber_demo","createdAt":"2026-08-10T14:22:05.000Z","score":13,"upvoteRatio":0.93,"comments":8,"views":5200,"awards":0,"shares":4,"reposts":1,"topCountries":[{"country":"US","name":"United States","percent":41.2},{"country":"GB","name":"United Kingdom","percent":9.8},{"country":"DE","name":"Germany","percent":6.1},{"country":null,"name":"Other","percent":42.9}],"authorRank":2,"locked":false,"nsfw":false,"warnings":[{"field":"views","code":"rounded","message":"Reddit shows views rounded: 5.2K views"}],"checkedAt":"2026-08-12T10:05:12.000Z"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","status":"ok","readAs":"other","permalink":"https://www.reddit.com/r/webdev/comments/1abd345/how_do_you_schedule_reddit_posts/","community":"r/webdev","title":"How do you schedule Reddit posts?","author":"frontend_fran","createdAt":"2026-08-03T09:41:30.000Z","score":1001,"upvoteRatio":0.96,"comments":5348,"views":null,"awards":3,"shares":null,"reposts":null,"topCountries":null,"locked":false,"nsfw":false,"warnings":[{"field":"views","code":"author_only","message":"Reddit shows views only to the post author"},{"field":"shares","code":"author_only","message":"Reddit shows shares only to the post author"},{"field":"reposts","code":"author_only","message":"Reddit shows reposts only to the post author"},{"field":"topCountries","code":"author_only","message":"Reddit shows the countries with the most views only to the post author"}],"checkedAt":"2026-08-12T10:05:31.000Z"},{"url":"https://www.reddit.com/comments/1abe456/","postId":"1abe456","status":"removed","readAs":"author","permalink":"https://www.reddit.com/r/example/comments/1abe456/queber_launch_week/","community":"r/example","title":"Queber launch week","author":"queber_demo","createdAt":"2026-08-11T18:05:44.000Z","score":1,"upvoteRatio":1,"comments":0,"views":null,"awards":null,"shares":null,"reposts":null,"topCountries":null,"locked":false,"nsfw":false,"removalMessage":"Sorry, this post has been removed by the moderators of r/example.","warnings":[{"field":"views","code":"not_shown","message":"Reddit did not show views for this post"},{"field":"shares","code":"not_shown","message":"Reddit did not show shares"},{"field":"reposts","code":"not_shown","message":"Reddit did not show reposts"},{"field":"topCountries","code":"not_shown","message":"Reddit did not show the countries with the most views"}],"checkedAt":"2026-08-12T10:05:49.000Z"},{"url":"https://www.reddit.com/u/queber_demo/comments/1abf567/","postId":"1abf567","community":"u/queber_demo","status":"not_found","warnings":[],"checkedAt":"2026-08-12T10:06:02.000Z"},{"url":"https://www.reddit.com/r/photography/s/aB3dE5fG7h","community":"r/photography","status":"failed","nsfw":true,"error":"Reddit hides this post until the account confirms it is over 18. Turn on mature content in this Reddit account to read it","errorCode":"mature_content_hidden","warnings":[],"checkedAt":"2026-08-12T10:06:13.000Z"}],"summary":{"total":5,"read":4,"removed":1,"notFound":1,"failed":1}}}}},{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"completed","source":"api","pause":"10-20","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z","startedAt":"2026-08-12T09:40:56.000Z","completedAt":"2026-08-12T09:41:07.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1a2b3c4/we_shipped_scheduled_reddit_posting/","resultDescription":"Published text post in r/webdev"}],"total":236,"nextCursor":"eyJ2IjoxLCJxIjoiTFRXdlNuZzNjcUVyIiwiZCI6eyI2YjFmMmMzZC00ZTVmLTRhNmItOGM3ZC05ZTBmMWEyYjNjNGQiOnsiYyI6ImV5SnpkR0Z5ZENJNklqSXdNall0TURndE1USlVNRGs2TkRBNk5UVXVNREF3V2lJc0ltbGtJam9pT1dNNFlqZGhOalV0TkRNeU1TMDBaakJsTFRsa09HTXROMkkyWVRWbU5HVXpaREl4SW4wIn19fQ"}}}},"400":{"description":"Bad request. validation_error: a query parameter is malformed, or cursor came from other filters or another sort. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"validation_error","message":"limit must be a number from 1 to 500"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_not_found","message":"No Queber Desktop with id \"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d\" is connected to this account.","desktops":[{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_multiple_sessions","message":"Multiple Queber Desktop apps are connected to this account. Close all but one Queber Desktop app and try again."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}":{"get":{"operationId":"getJob","summary":"Get one automation job","description":"Reads one job with its logs. A finished Reddit post has resultUrl; a finished post read has one result per link in resultData.reddit.post_read, with comment counts; getJobComments reads the comments. Poll until status is completed, failed, or cancelled; a read with more links takes longer.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:read"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Automation job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, cleared when the job is queued again. A post read keeps its results in reddit.post_read, a comment its permalink in reddit.comment; poll getJob until the job completes.","properties":{"reddit":{"type":"object","properties":{"post_read":{"type":"object","description":"Result of a Reddit post read: one item per link, in the order of the links.","properties":{"items":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"The link as the job stores it."},"postId":{"type":"string","description":"Reddit post id. A share link gets it from the page; missing when the page did not open."},"status":{"type":"string","enum":["ok","removed","not_found","failed"],"description":"ok: the post was read. removed: Reddit shows a removal banner. not_found: Reddit has no such post. failed: the link could not be read; see error. Allowed values: ok, removed, not_found, failed."},"readAs":{"type":"string","enum":["author","other"],"description":"author when the profile that ran the read wrote the post. Reddit shows views, shares, reposts, the countries with the most views, and removal banners of own posts only to the author. Allowed values: author, other."},"permalink":{"type":"string"},"community":{"type":"string","description":"r/<name>, or u/<name> for a profile post."},"title":{"type":"string"},"author":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"score":{"type":["integer","null"]},"upvoteRatio":{"type":["number","null"],"description":"From 0 to 1."},"comments":{"type":["integer","null"]},"views":{"type":["number","null"],"description":"Only on the profile's own posts, rounded as Reddit shows them (5.2K is 5200); null on other posts. Each read of an own post adds one view on Reddit."},"awards":{"type":["integer","null"],"description":"Awards the post received. Reddit leaves the count off removed posts."},"shares":{"type":["integer","null"],"description":"Times the post was shared. Only on the profile's own live posts, from Reddit's stats page of the post; null otherwise."},"reposts":{"type":["integer","null"],"description":"Times the post was reposted to other communities. Only on the profile's own live posts; null otherwise."},"topCountries":{"type":["array","null"],"description":"The countries with the most views, then the rest of the world, as Reddit's stats page lists them. Only on the profile's own live posts; empty when Reddit lists none yet; null otherwise. Each read of an own post adds a view from the profile's own country.","items":{"type":"object","properties":{"country":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 code from Reddit's flag; null for the rest of the world."},"name":{"type":"string","description":"The name as Reddit wrote it, in the account's language."},"percent":{"type":"number","description":"Share of the views, 0 to 100."}},"required":["country","name","percent"],"additionalProperties":true}},"authorRank":{"type":["integer","null"],"description":"The post's place among all the author's posts when Reddit names one (\"This is your #1 post of all time\"); null when it names none. Only when the profile's own post stats were read."},"locked":{"type":"boolean"},"nsfw":{"type":"boolean"},"removalMessage":{"type":"string","description":"Only on removed: the banner text exactly as Reddit shows it, in the account's language."},"error":{"type":"string","description":"Only on failed: why the link could not be read."},"errorCode":{"type":"string","enum":["mature_content_hidden"],"description":"Only on failed, when the reason is known. mature_content_hidden: Reddit hides the post until the account confirms it is over 18. Allowed values: mature_content_hidden."},"warnings":{"type":"array","description":"Values Reddit did not show as an exact number. A null value always has a warning.","items":{"type":"object","properties":{"field":{"type":"string","enum":["score","upvoteRatio","comments","views","awards","shares","reposts","topCountries"],"description":"The value the warning is about. Allowed values: score, upvoteRatio, comments, views, awards, shares, reposts, topCountries."},"code":{"type":"string","enum":["author_only","not_shown","rounded"],"description":"author_only: Reddit shows it only to the post author. not_shown: Reddit did not show it. rounded: the number is Reddit's rounded value. Allowed values: author_only, not_shown, rounded."},"message":{"type":"string"}},"required":["field","code","message"],"additionalProperties":true}},"commentThread":{"type":"object","description":"Only when the read asked for comments and the post page showed them.","properties":{"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"The order the comments were loaded in. Allowed values: best, top, new, old, controversial, qa."},"total":{"type":["integer","null"],"description":"Comments Reddit counts on the post, deleted and hidden ones included."},"loaded":{"type":"integer","description":"Comments the read loaded; getJobComments returns them page by page."},"complete":{"type":"boolean","description":"Every comment Reddit offered on the page was loaded."},"stoppedBy":{"type":"string","enum":["limit","run_limit","time"],"description":"Why the thread holds fewer comments than the post has. limit: the per-post limit. run_limit: the run's 5,000-comment budget. time: loading took longer than the 2 minutes a post gets. Allowed values: limit, run_limit, time."},"comments":{"type":"array","description":"Only in the desktop app and its exports; getJob and listJobs leave them out, getJobComments pages them.","items":{"type":"object","properties":{"id":{"type":"string","description":"Reddit comment id, as in its permalink (.../comment/<id>/)."},"parentId":{"type":["string","null"],"description":"Id of the comment it answers; null for a comment on the post itself."},"depth":{"type":"integer","description":"0 for a comment on the post, 1 for a reply to it, and so on."},"author":{"type":["string","null"],"description":"Null when the account is gone."},"isOp":{"type":"boolean","description":"The post's author wrote it."},"body":{"type":"string","description":"Text as shown, paragraphs separated by a blank line; empty for deleted and removed comments; at most 10,000 characters."},"score":{"type":["integer","null"],"description":"Null when the community hides comment scores for now."},"awards":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":"string","format":"date-time","description":"When the author last edited it; only on edited comments."},"permalink":{"type":"string"},"collapsed":{"type":"boolean","description":"Reddit collapses it in the thread, for example for a low score."},"state":{"type":"string","enum":["ok","deleted","removed"],"description":"ok: a comment with its author. deleted: the author or the account deleted it. removed: Reddit or the moderators took it down. Allowed values: ok, deleted, removed."},"moreReplies":{"type":["integer","null"],"description":"Only when replies under it were not loaded: their number as Reddit shows it (\"4 more replies\"), null when Reddit shows no number (a deep thread continues on its own page)."}},"required":["id","parentId","depth","author","isOp","body","score","awards","collapsed","state"],"additionalProperties":true}}},"required":["sort","total","loaded","complete"],"additionalProperties":true},"checkedAt":{"type":"string","format":"date-time"}},"required":["url","status","warnings","checkedAt"],"additionalProperties":true}},"summary":{"type":"object","description":"Counts over items. read counts links read to a result, removed and not found included; the run is charged only when read is above 0.","properties":{"total":{"type":"integer"},"read":{"type":"integer"},"removed":{"type":"integer"},"notFound":{"type":"integer"},"failed":{"type":"integer"}},"required":["total","read","removed","notFound","failed"],"additionalProperties":true}},"required":["items","summary"],"additionalProperties":true},"comment":{"type":"object","description":"Result of a Reddit comment; resultUrl holds the same permalink.","properties":{"commentId":{"type":"string","description":"Base-36 id of the new comment."},"permalink":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"},"parentId":{"type":["string","null"],"description":"The comment answered; null for a comment on the post."},"repliedTo":{"type":"object","properties":{"commentId":{"type":"string"},"author":{"type":["string","null"]}},"additionalProperties":true},"alreadyPosted":{"type":"boolean","description":"The account's same comment was already there, left by an earlier run of this job that stopped after sending it; nothing was sent again and nothing is charged."},"postedAt":{"type":"string","format":"date-time"}},"required":["commentId","permalink","parentId","postedAt"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"examples":{"completedPost":{"summary":"Published Reddit post","value":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"completed","source":"api","pause":"10-20","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z","startedAt":"2026-08-12T09:40:56.000Z","completedAt":"2026-08-12T09:41:07.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1a2b3c4/we_shipped_scheduled_reddit_posting/","resultDescription":"Published text post in r/webdev","logs":[{"id":"1a2b3c4d-5e6f-4708-8192-a3b4c5d6e7f8","at":"2026-08-12T09:41:07.000Z","level":"success","title":"Post published","description":"Reddit accepted the post and returned a live URL.","stageId":"finished"}]}}},"completedPostRead":{"summary":"Finished Reddit post read with its results","value":{"job":{"id":"e2d4f6a8-1b3c-4d5e-8f70-9a1b2c3d4e5f","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"post_read","status":"completed","source":"api","pause":"off","attempts":1,"platformData":{"reddit":{"post_read":{"links":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","community":"r/SideProject"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","community":"r/webdev"},{"url":"https://www.reddit.com/comments/1abe456/","postId":"1abe456"},{"url":"https://www.reddit.com/u/queber_demo/comments/1abf567/","postId":"1abf567","community":"u/queber_demo"},{"url":"https://www.reddit.com/r/photography/s/aB3dE5fG7h","community":"r/photography"}]}}},"createdAt":"2026-08-12T10:05:00.000Z","startedAt":"2026-08-12T10:05:01.000Z","completedAt":"2026-08-12T10:06:14.000Z","resultDescription":"Read 4 of 5 posts: 1 removed, 1 not found, 1 failed","resultData":{"reddit":{"post_read":{"items":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","status":"ok","readAs":"author","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","community":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","author":"queber_demo","createdAt":"2026-08-10T14:22:05.000Z","score":13,"upvoteRatio":0.93,"comments":8,"views":5200,"awards":0,"shares":4,"reposts":1,"topCountries":[{"country":"US","name":"United States","percent":41.2},{"country":"GB","name":"United Kingdom","percent":9.8},{"country":"DE","name":"Germany","percent":6.1},{"country":null,"name":"Other","percent":42.9}],"authorRank":2,"locked":false,"nsfw":false,"warnings":[{"field":"views","code":"rounded","message":"Reddit shows views rounded: 5.2K views"}],"checkedAt":"2026-08-12T10:05:12.000Z"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","status":"ok","readAs":"other","permalink":"https://www.reddit.com/r/webdev/comments/1abd345/how_do_you_schedule_reddit_posts/","community":"r/webdev","title":"How do you schedule Reddit posts?","author":"frontend_fran","createdAt":"2026-08-03T09:41:30.000Z","score":1001,"upvoteRatio":0.96,"comments":5348,"views":null,"awards":3,"shares":null,"reposts":null,"topCountries":null,"locked":false,"nsfw":false,"warnings":[{"field":"views","code":"author_only","message":"Reddit shows views only to the post author"},{"field":"shares","code":"author_only","message":"Reddit shows shares only to the post author"},{"field":"reposts","code":"author_only","message":"Reddit shows reposts only to the post author"},{"field":"topCountries","code":"author_only","message":"Reddit shows the countries with the most views only to the post author"}],"checkedAt":"2026-08-12T10:05:31.000Z"},{"url":"https://www.reddit.com/comments/1abe456/","postId":"1abe456","status":"removed","readAs":"author","permalink":"https://www.reddit.com/r/example/comments/1abe456/queber_launch_week/","community":"r/example","title":"Queber launch week","author":"queber_demo","createdAt":"2026-08-11T18:05:44.000Z","score":1,"upvoteRatio":1,"comments":0,"views":null,"awards":null,"shares":null,"reposts":null,"topCountries":null,"locked":false,"nsfw":false,"removalMessage":"Sorry, this post has been removed by the moderators of r/example.","warnings":[{"field":"views","code":"not_shown","message":"Reddit did not show views for this post"},{"field":"shares","code":"not_shown","message":"Reddit did not show shares"},{"field":"reposts","code":"not_shown","message":"Reddit did not show reposts"},{"field":"topCountries","code":"not_shown","message":"Reddit did not show the countries with the most views"}],"checkedAt":"2026-08-12T10:05:49.000Z"},{"url":"https://www.reddit.com/u/queber_demo/comments/1abf567/","postId":"1abf567","community":"u/queber_demo","status":"not_found","warnings":[],"checkedAt":"2026-08-12T10:06:02.000Z"},{"url":"https://www.reddit.com/r/photography/s/aB3dE5fG7h","community":"r/photography","status":"failed","nsfw":true,"error":"Reddit hides this post until the account confirms it is over 18. Turn on mature content in this Reddit account to read it","errorCode":"mature_content_hidden","warnings":[],"checkedAt":"2026-08-12T10:06:13.000Z"}],"summary":{"total":5,"read":4,"removed":1,"notFound":1,"failed":1}}}},"logs":[{"id":"5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9","at":"2026-08-12T10:06:14.000Z","level":"success","title":"Automation completed","description":"Read 4 of 5 posts: 1 removed, 1 not found, 1 failed","stageId":"finished"}]}}},"completedPostReadWithComments":{"summary":"Finished Reddit post read with the comments under the post","value":{"job":{"id":"f3e5a7b9-2c4d-4e6f-9a81-0b2c3d4e5f60","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"post_read","status":"completed","source":"api","pause":"off","attempts":1,"platformData":{"reddit":{"post_read":{"links":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","community":"r/SideProject"}],"comments":{"limit":50,"sort":"top"}}}},"createdAt":"2026-08-12T10:05:00.000Z","startedAt":"2026-08-12T11:00:01.000Z","completedAt":"2026-08-12T11:00:31.000Z","resultDescription":"Read 1 of 1 posts: 0 removed, 0 not found, 0 failed","resultData":{"reddit":{"post_read":{"items":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","status":"ok","readAs":"author","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","community":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","author":"queber_demo","createdAt":"2026-08-10T14:22:05.000Z","score":13,"upvoteRatio":0.93,"comments":8,"views":5200,"awards":0,"shares":4,"reposts":1,"topCountries":[{"country":"US","name":"United States","percent":41.2},{"country":"GB","name":"United Kingdom","percent":9.8},{"country":"DE","name":"Germany","percent":6.1},{"country":null,"name":"Other","percent":42.9}],"authorRank":2,"locked":false,"nsfw":false,"warnings":[{"field":"views","code":"rounded","message":"Reddit shows views rounded: 5.2K views"}],"checkedAt":"2026-08-12T11:00:30.000Z","commentThread":{"sort":"top","total":8,"loaded":3,"complete":false}}],"summary":{"total":1,"read":1,"removed":0,"notFound":0,"failed":0}}}}}}},"completedComment":{"summary":"Posted Reddit reply with its permalink","value":{"job":{"id":"b7c9d1e3-5f7a-4b9c-8d1e-3f5a7b9c1d2e","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"comment","status":"completed","source":"api","pause":"off","attempts":1,"platformData":{"reddit":{"comment":{"post":{"url":"https://www.reddit.com/r/webdev/comments/1abc234/","postId":"1abc234","community":"r/webdev"},"replyTo":{"kind":"comment","commentId":"ohd7k2m"},"body":"Glad it works for you!"}}},"createdAt":"2026-08-12T10:05:00.000Z","startedAt":"2026-08-12T10:05:01.000Z","completedAt":"2026-08-12T10:05:52.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohe2p4q/","resultDescription":"Replied to u/quiet_reader in r/webdev","resultData":{"reddit":{"comment":{"commentId":"ohe2p4q","permalink":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohe2p4q/","postId":"1abc234","community":"r/webdev","parentId":"ohd7k2m","repliedTo":{"commentId":"ohd7k2m","author":"quiet_reader"},"postedAt":"2026-08-12T10:05:37.000Z"}}}}}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_selection_required","message":"Job 9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21 exists on several Queber Desktop apps, usually because app data was copied to another computer. Repeat the request with desktopId set to one of error.desktops.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/logs":{"get":{"operationId":"getJobLogs","summary":"Get automation job logs","description":"Use this to explain what happened during a job, especially after a failure.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:read"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Job progress logs.","content":{"application/json":{"schema":{"type":"object","properties":{"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}},"total":{"type":"integer"}},"required":["logs","total"]},"example":{"logs":[{"id":"0f9e8d7c-6b5a-4938-8271-6c5d4e3f2a1b","at":"2026-08-12T09:40:58.000Z","level":"info","title":"Opening browser profile","description":"Using Reddit main.","stageId":"browser-open"},{"id":"1a2b3c4d-5e6f-4708-8192-a3b4c5d6e7f8","at":"2026-08-12T09:41:07.000Z","level":"success","title":"Post published","description":"Reddit accepted the post and returned a live URL.","stageId":"finished"}],"total":2}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_selection_required","message":"Job 9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21 exists on several Queber Desktop apps, usually because app data was copied to another computer. Repeat the request with desktopId set to one of error.desktops.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/comments":{"get":{"operationId":"getJobComments","summary":"Get the comments a post check read, page by page","description":"Reads the comments a finished Reddit post check loaded, in page order (a comment before its replies), each with postId and postUrl. limit is 100 by default and 500 at most; while nextCursor is not null, call again with it. postId keeps one post.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:read"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id of a finished post check with comments.","example":"f3e5a7b9-2c4d-4e6f-9a81-0b2c3d4e5f60"},{"name":"postId","in":"query","required":false,"schema":{"type":"string"},"description":"Only the comments of this post (resultData.reddit.post_read.items[].postId).","example":"1abc234"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500},"description":"Comments per page, 100 by default and 500 at most.","example":100},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"nextCursor of the previous page, with the same jobId and postId; leave it out for the first page.","example":"eyJqIjoiZjNlNWE3YjktMmM0ZC00ZTZmLTlhODEtMGIyYzNkNGU1ZjYwIiwicCI6bnVsbCwibyI6MTAwfQ"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"One page of the comments a post check loaded.","content":{"application/json":{"schema":{"type":"object","properties":{"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Reddit comment id, as in its permalink (.../comment/<id>/)."},"parentId":{"type":["string","null"],"description":"Id of the comment it answers; null for a comment on the post itself."},"depth":{"type":"integer","description":"0 for a comment on the post, 1 for a reply to it, and so on."},"author":{"type":["string","null"],"description":"Null when the account is gone."},"isOp":{"type":"boolean","description":"The post's author wrote it."},"body":{"type":"string","description":"Text as shown, paragraphs separated by a blank line; empty for deleted and removed comments; at most 10,000 characters."},"score":{"type":["integer","null"],"description":"Null when the community hides comment scores for now."},"awards":{"type":["integer","null"]},"createdAt":{"type":"string","format":"date-time"},"editedAt":{"type":"string","format":"date-time","description":"When the author last edited it; only on edited comments."},"permalink":{"type":"string"},"collapsed":{"type":"boolean","description":"Reddit collapses it in the thread, for example for a low score."},"state":{"type":"string","enum":["ok","deleted","removed"],"description":"ok: a comment with its author. deleted: the author or the account deleted it. removed: Reddit or the moderators took it down. Allowed values: ok, deleted, removed."},"moreReplies":{"type":["integer","null"],"description":"Only when replies under it were not loaded: their number as Reddit shows it (\"4 more replies\"), null when Reddit shows no number (a deep thread continues on its own page)."},"postId":{"type":"string","description":"The post the comment is under."},"postUrl":{"type":"string","description":"The post's permalink, or the link as the job stores it."}},"required":["id","parentId","depth","author","isOp","body","score","awards","collapsed","state"],"additionalProperties":true}},"total":{"type":"integer","description":"Comments of the job, or of postId, over all pages."},"nextCursor":{"type":["string","null"],"description":"Send it as cursor for the next page; null on the last page."}},"required":["comments","total","nextCursor"]},"example":{"comments":[{"id":"kq1a2b3","parentId":null,"depth":0,"author":"frontend_fran","isOp":false,"body":"Does the queue keep a pause between posts of one profile?","score":6,"awards":0,"createdAt":"2026-08-10T15:02:11.000Z","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/comment/kq1a2b3/","collapsed":false,"state":"ok","postId":"1abc234","postUrl":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/"},{"id":"kq1c4d5","parentId":"kq1a2b3","depth":1,"author":"queber_demo","isOp":true,"body":"Yes: set it per profile, and each post keeps its own pause.\n\nScheduled posts move later when they are too close.","score":4,"awards":1,"createdAt":"2026-08-10T15:20:47.000Z","editedAt":"2026-08-10T15:23:02.000Z","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/comment/kq1c4d5/","collapsed":false,"state":"ok","moreReplies":5,"postId":"1abc234","postUrl":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/"},{"id":"kq1e6f7","parentId":null,"depth":0,"author":null,"isOp":false,"body":"","score":null,"awards":null,"createdAt":"2026-08-10T16:41:09.000Z","permalink":"https://www.reddit.com/r/SideProject/comments/1abc234/comment/kq1e6f7/","collapsed":true,"state":"deleted","postId":"1abc234","postUrl":"https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/"}],"total":3,"nextCursor":null}}}},"400":{"description":"Bad request. validation_error: a query parameter is malformed, or cursor came from other filters or another sort. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"validation_error","message":"limit must be a number from 1 to 500"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_selection_required","message":"Job f3e5a7b9-2c4d-4e6f-9a81-0b2c3d4e5f60 exists on several Queber Desktop apps, usually because app data was copied to another computer. Repeat the request with desktopId set to one of error.desktops.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/progress":{"get":{"operationId":"getJobProgress","summary":"Get concise job progress","description":"Use this for a short status summary of one job instead of the full log list.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:read"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"desktopId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","example":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"responses":{"200":{"description":"Job progress.","content":{"application/json":{"schema":{"type":"object","properties":{"progress":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Allowed values: pending, running, paused, completed, failed, cancelled."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"target":{"type":"string"},"scheduledAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string","description":"Short result line, for example the counts of a Reddit post read. The full result is in getJob."},"error":{"type":"string"},"logCount":{"type":"integer"},"lastLog":{"type":["object","null"],"properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}},"additionalProperties":true}},"required":["progress"]},"example":{"progress":{"jobId":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","status":"completed","platform":"reddit","automationType":"posting","target":"r/webdev","startedAt":"2026-08-12T09:40:56.000Z","completedAt":"2026-08-12T09:41:07.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1a2b3c4/we_shipped_scheduled_reddit_posting/","resultDescription":"Published text post in r/webdev","logCount":2,"lastLog":{"id":"1a2b3c4d-5e6f-4708-8192-a3b4c5d6e7f8","at":"2026-08-12T09:41:07.000Z","level":"success","title":"Post published","description":"Reddit accepted the post and returned a live URL.","stageId":"finished"}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:read"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_selection_required","message":"Job 9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21 exists on several Queber Desktop apps, usually because app data was copied to another computer. Repeat the request with desktopId set to one of error.desktops.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time; repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/run":{"post":{"operationId":"runJobNow","summary":"Create and run a job now","description":"Creates a job that runs as soon as possible: a Reddit post (platformData.reddit.posting; import media first), a post read (reddit.post_read.links), or a comment (reddit.comment: link, body). Poll getJob for results. The profile pause may move the start: see scheduledAt.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write","mcp:automation:run"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"Queber browser profile id that runs the automation."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false,"description":"Desktop Job platformData. For Reddit posting, send content under reddit.posting; for a Reddit post read, links under reddit.post_read; for a Reddit comment, link and body under reddit.comment."},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause kept between this post and other posts of the same profile: off, or a range in minutes. Defaults to the profile's setting in the app. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"required":["profileId","platform","automationType","platformData"],"additionalProperties":false},"examples":{"textPost":{"summary":"Text post","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}}}},"linkPost":{"summary":"Link post (url required)","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/webdev","title":"Queber Desktop 1.1.6 release notes","type":"link","url":"https://queber.app/releases","flairId":null}}}}},"imagePost":{"summary":"Single image post with its own pause (import media first)","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","type":"image","body":"Screenshot of the new queue screen.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55"}}},"pause":"20-40"}},"imageGalleryPost":{"summary":"Image gallery, up to 20 images","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop 1.1.6 - before and after","type":"image","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"},{"id":"c2b1a0f9-8e7d-4c6b-a594-3d2e1f0a9b8c","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\queue-screen.png","type":"image","name":"queue-screen.png"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","tags":["spoiler"]}}}}},"videoPost":{"summary":"Video post, one video per post","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop - 40 second demo","type":"video","media":[{"id":"a9b8c7d6-5e4f-4a3b-9c8d-7e6f5a4b3c2d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-demo.mp4","type":"video","name":"launch-demo.mp4"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55"}}}}},"postRead":{"summary":"Read Reddit posts, every accepted link form (results come in resultData; poll getJob)","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"post_read","platformData":{"reddit":{"post_read":{"links":["https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","https://old.reddit.com/r/webdev/comments/1abd345/how_do_you_schedule_reddit_posts/","https://redd.it/1abe456","https://www.reddit.com/user/queber_demo/comments/1abf567/launch_notes/","https://www.reddit.com/r/photography/s/aB3dE5fG7h"]}}}}},"comment":{"summary":"Comment on a Reddit post (resultUrl and resultData.reddit.comment hold the new comment)","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"comment","platformData":{"reddit":{"comment":{"link":"https://www.reddit.com/r/webdev/comments/1abc234/how_we_run_reddit_posting/","body":"Thanks for the write-up, the queue screenshot helped."}}}}},"commentReply":{"summary":"Reply to one comment, by an id from checkRedditCommentTarget","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"comment","platformData":{"reddit":{"comment":{"link":"https://www.reddit.com/r/webdev/comments/1abc234/how_we_run_reddit_posting/","replyToCommentId":"ohd7k2m","body":"Glad it works for you!"}}}}},"commentReplyByLink":{"summary":"Reply to the comment a comment link names, with a GIF","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"comment","platformData":{"reddit":{"comment":{"link":"https://www.reddit.com/r/webdev/comments/1abc234/comment/ohd7k2m/","body":"Exactly this.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\thumbs-up.gif","type":"image","name":"thumbs-up.gif"}]}}}}},"postReadWithComments":{"summary":"Read Reddit posts with their comments, top first, up to 50 per post (getJob returns the comments)","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"post_read","platformData":{"reddit":{"post_read":{"links":["https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/"],"comments":{"limit":50,"sort":"top"}}}}}},"textPostWithInlineMedia":{"summary":"Text post with inline image","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/webdev","title":"How we run Reddit posting from real browser profiles","type":"text","body":"Architecture in one screenshot.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"}],"flairId":null}}}}}}}}},"responses":{"201":{"description":"Created job. It waits in the local queue until it starts.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"examples":{"post":{"summary":"Reddit post queued","value":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"pending","source":"api","pause":"10-20","attempts":0,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z"}}},"postRead":{"summary":"Reddit post read queued, links parsed","value":{"job":{"id":"e2d4f6a8-1b3c-4d5e-8f70-9a1b2c3d4e5f","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"post_read","status":"pending","source":"api","pause":"off","attempts":0,"platformData":{"reddit":{"post_read":{"links":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","community":"r/SideProject"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","community":"r/webdev"},{"url":"https://www.reddit.com/comments/1abe456/","postId":"1abe456"},{"url":"https://www.reddit.com/u/queber_demo/comments/1abf567/","postId":"1abf567","community":"u/queber_demo"},{"url":"https://www.reddit.com/r/photography/s/aB3dE5fG7h","community":"r/photography"}]}}},"createdAt":"2026-08-12T10:05:00.000Z"}}},"comment":{"summary":"Reddit reply queued, the link resolved to the post and the comment to answer","value":{"job":{"id":"b7c9d1e3-5f7a-4b9c-8d1e-3f5a7b9c1d2e","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"comment","status":"pending","source":"api","pause":"off","attempts":0,"platformData":{"reddit":{"comment":{"post":{"url":"https://www.reddit.com/r/webdev/comments/1abc234/","postId":"1abc234","community":"r/webdev"},"replyTo":{"kind":"comment","commentId":"ohd7k2m"},"body":"Glad it works for you!"}}},"createdAt":"2026-08-12T10:05:00.000Z"}}}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"examples":{"postReadNotRedditPosts":{"summary":"Post read: a link is not a Reddit post","value":{"error":{"code":"validation_error","message":"These are not links to Reddit posts: https://example.com/x"}}},"postReadTooManyLinks":{"summary":"Post read: more links than the plan reads per run (the number comes from the plan)","value":{"error":{"code":"validation_error","message":"Your plan reads up to 100 links per run; this read has 120"}}},"postReadNotInPlan":{"summary":"Post read: the plan does not include reading posts","value":{"error":{"code":"validation_error","message":"This automation is not included in your plan (reddit.post_read). Switch plans to use it."}}},"commentNotRedditLink":{"summary":"Comment: the link is not a Reddit post or comment","value":{"error":{"code":"validation_error","message":"Not a link to a Reddit post or comment: https://example.com/x"}}},"commentTwoTargets":{"summary":"Comment: the link and replyToCommentId name different comments","value":{"error":{"code":"validation_error","message":"The link points to comment ohd7k2m, replyToCommentId to ohd9x1a"}}},"commentTooManyMedia":{"summary":"Comment: more than one image, GIF, or video","value":{"error":{"code":"validation_error","message":"A Reddit comment takes one image, GIF, or video; this one has 2"}}},"missingField":{"summary":"A required field is missing","value":{"error":{"code":"validation_error","message":"platformData is required"}}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write mcp:automation:run"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Profile not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. media_on_other_desktop: import the media again with this profileId. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"examples":{"idempotencyKeyReused":{"summary":"Idempotency-Key already used for another request","value":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}},"mediaOnOtherDesktop":{"summary":"Media imported on another desktop than the profile's","value":{"error":{"code":"media_on_other_desktop","message":"Media C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png was imported on another Queber Desktop. Import it again with profileId 3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607 so it lands on the desktop that runs this profile.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"429":{"description":"Too many requests. reddit_rate_limited: Reddit is limiting metadata requests. rate_limited: Queber is limiting requests. Wait for Retry-After (also error.retryAfterSeconds), then repeat the request with the same Idempotency-Key.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"reddit_rate_limited","message":"Reddit target analysis failed: Reddit is rate limiting requests. Try again in 30 seconds","retryable":true,"retryAfterSeconds":30}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Reddit target analysis failed: fetch failed"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/schedule":{"post":{"operationId":"scheduleJob","summary":"Schedule an automation job","description":"Creates a job for a future ISO datetime: a Reddit post (platformData.reddit.posting; import media first), a post read (reddit.post_read.links), or a comment (reddit.comment: link, body). Poll getJob for results. The profile pause may move the start: see scheduledAt.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write","mcp:automation:run"]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"profileId":{"type":"string","description":"Queber browser profile id that runs the automation."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false,"description":"Desktop Job platformData. For Reddit posting, send content under reddit.posting; for a Reddit post read, links under reddit.post_read; for a Reddit comment, link and body under reddit.comment."},"scheduledAt":{"type":"string","format":"date-time","description":"Future ISO datetime."},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause kept between this post and other posts of the same profile: off, or a range in minutes. Defaults to the profile's setting in the app. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"required":["profileId","platform","automationType","platformData","scheduledAt"],"additionalProperties":false},"examples":{"scheduledImagePost":{"summary":"Scheduled image post","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","type":"image","body":"Screenshot of the new queue screen.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","tags":["spoiler"]}}},"scheduledAt":"2026-08-13T07:00:00.000Z"}},"scheduledTextPost":{"summary":"Scheduled text post","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"scheduledAt":"2026-08-14T06:30:00.000Z"}},"scheduledLinkPost":{"summary":"Scheduled link post without a pause","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"posting","platformData":{"reddit":{"posting":{"target":"r/webdev","title":"Queber Desktop 1.1.6 release notes","type":"link","url":"https://queber.app/releases","flairId":null}}},"scheduledAt":"2026-08-15T09:15:00.000Z","pause":"off"}},"scheduledPostRead":{"summary":"Read Reddit posts at a set time, for example a day after publishing","value":{"profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","platform":"reddit","automationType":"post_read","platformData":{"reddit":{"post_read":{"links":["https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","https://old.reddit.com/r/webdev/comments/1abd345/how_do_you_schedule_reddit_posts/"]}}},"scheduledAt":"2026-08-13T08:00:00.000Z"}}}}}},"responses":{"201":{"description":"Scheduled job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"examples":{"movedPost":{"summary":"Reddit post scheduled; the profile pause moved its start","value":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"pending","source":"api","pause":"10-20","attempts":0,"platformData":{"reddit":{"posting":{"target":"r/SideProject","title":"Queber Desktop 1.1.6 - queue view","type":"image","body":"Screenshot of the new queue screen.","media":[{"id":"d4c3b2a1-9f8e-4d7c-b6a5-1e2f3a4b5c6d","url":"C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png","type":"image","name":"launch-promo.png"}],"flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","tags":["spoiler"]}}},"createdAt":"2026-08-12T09:40:55.000Z","scheduledAt":"2026-08-13T07:14:00.000Z","requestedScheduledAt":"2026-08-13T07:00:00.000Z","startMovedByPause":true}}},"scheduledPostRead":{"summary":"Reddit post read scheduled","value":{"job":{"id":"e2d4f6a8-1b3c-4d5e-8f70-9a1b2c3d4e5f","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"post_read","status":"pending","source":"api","pause":"off","attempts":0,"platformData":{"reddit":{"post_read":{"links":[{"url":"https://www.reddit.com/r/SideProject/comments/1abc234/","postId":"1abc234","community":"r/SideProject"},{"url":"https://www.reddit.com/r/webdev/comments/1abd345/","postId":"1abd345","community":"r/webdev"}]}}},"createdAt":"2026-08-12T10:05:00.000Z","scheduledAt":"2026-08-13T08:00:00.000Z"}}}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"examples":{"postReadNotRedditPosts":{"summary":"Post read: a link is not a Reddit post","value":{"error":{"code":"validation_error","message":"These are not links to Reddit posts: https://example.com/x"}}},"postReadTooManyLinks":{"summary":"Post read: more links than the plan reads per run (the number comes from the plan)","value":{"error":{"code":"validation_error","message":"Your plan reads up to 100 links per run; this read has 120"}}},"postReadNotInPlan":{"summary":"Post read: the plan does not include reading posts","value":{"error":{"code":"validation_error","message":"This automation is not included in your plan (reddit.post_read). Switch plans to use it."}}},"commentNotRedditLink":{"summary":"Comment: the link is not a Reddit post or comment","value":{"error":{"code":"validation_error","message":"Not a link to a Reddit post or comment: https://example.com/x"}}},"commentTwoTargets":{"summary":"Comment: the link and replyToCommentId name different comments","value":{"error":{"code":"validation_error","message":"The link points to comment ohd7k2m, replyToCommentId to ohd9x1a"}}},"commentTooManyMedia":{"summary":"Comment: more than one image, GIF, or video","value":{"error":{"code":"validation_error","message":"A Reddit comment takes one image, GIF, or video; this one has 2"}}},"missingField":{"summary":"A required field is missing","value":{"error":{"code":"validation_error","message":"platformData is required"}}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write mcp:automation:run"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Profile not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. media_on_other_desktop: import the media again with this profileId. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"examples":{"idempotencyKeyReused":{"summary":"Idempotency-Key already used for another request","value":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}},"mediaOnOtherDesktop":{"summary":"Media imported on another desktop than the profile's","value":{"error":{"code":"media_on_other_desktop","message":"Media C:\\Users\\alex\\AppData\\Roaming\\Queber\\post_resources\\launch-promo.png was imported on another Queber Desktop. Import it again with profileId 3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607 so it lands on the desktop that runs this profile.","desktops":[{"id":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d","name":"Office PC","appVersion":"1.2.9","connectedAt":"2026-08-12T08:31:20.000Z","legacy":false},{"id":"0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a","name":"Laptop","appVersion":"1.2.9","connectedAt":"2026-08-12T09:02:47.000Z","legacy":false}]}}}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"429":{"description":"Too many requests. reddit_rate_limited: Reddit is limiting metadata requests. rate_limited: Queber is limiting requests. Wait for Retry-After (also error.retryAfterSeconds), then repeat the request with the same Idempotency-Key.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"reddit_rate_limited","message":"Reddit target analysis failed: Reddit is rate limiting requests. Try again in 30 seconds","retryable":true,"retryAfterSeconds":30}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Reddit target analysis failed: fetch failed"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/update":{"post":{"operationId":"updateJob","summary":"Edit an automation job","description":"Edits a pending, paused, failed, or cancelled local job. content takes the automation's own fields: a post's text, media, flair, and tags; a comment's text and media; a post check's links and comments. scheduledAt moves or clears timing; pause changes the job's own pause.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAt":{"type":["string","null"],"format":"date-time","description":"Future ISO datetime, or null to clear timing."},"content":{"type":"object","description":"The automation's own fields. Post: title, body, url, type, media, flair, tags. Comment: body and media; its post and the comment it answers stay. Post check: links and comments.","properties":{"title":{"type":"string"},"body":{"type":"string","description":"Post or comment text, as when the job was created."},"url":{"type":["string","null"],"description":"Link URL. Send null to clear."},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"New post type for the job content. Allowed values: text, image, video, link, media."},"media":{"type":"array","description":"Replacement media items returned by importMedia; a comment takes at most one. Send [] to remove them.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"links":{"type":"array","minItems":1,"description":"Post check only: the new list of post links, checked like a new post check.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Post check only: true or { limit, sort } to read comments, false or null to stop reading them.","anyOf":[{"type":"boolean"},{"type":"null"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]},"flairId":{"type":["string","null"],"description":"Replacement Reddit post flair id. Send null to clear."},"flairText":{"type":["string","null"],"description":"Replacement flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair."},"tags":{"type":"array","description":"Replacement Reddit post tags. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}}},"additionalProperties":false},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause kept between this post and other posts of the same profile: off, or a range in minutes. Leave it out to keep the job's current pause. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"updateContent":{"summary":"Edit content and flair by text","value":{"content":{"title":"Updated launch notes","body":"Updated copy before the scheduled post runs.","flairText":"Showoff Saturday","tags":["spoiler"]}}},"updateComment":{"summary":"Edit the text of a waiting comment","value":{"content":{"body":"Thanks for the write-up, the queue screenshot helped a lot."}}},"updatePostCheck":{"summary":"Change the links of a post check and read 50 newest comments per post","value":{"content":{"links":["https://www.reddit.com/r/SideProject/comments/1abc234/queber_desktop_116_queue_view/","https://old.reddit.com/r/webdev/comments/1abd345/how_do_you_schedule_reddit_posts/"],"comments":{"limit":50,"sort":"new"}}}},"reschedule":{"summary":"Move a scheduled job","value":{"scheduledAt":"2026-08-16T10:30:00.000Z"}},"clearSchedule":{"summary":"Queue as soon as possible","value":{"scheduledAt":null}},"changePause":{"summary":"Turn off the pause for this job","value":{"pause":"off"}}}}}},"responses":{"200":{"description":"Updated job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"pending","source":"api","pause":"10-20","attempts":0,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"Updated launch notes","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":"5f7c1a2e-2b44-11ee-9d6b-0e2b1d3c4a55","tags":["spoiler"]}}},"createdAt":"2026-08-12T09:40:55.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"examples":{"notEditable":{"summary":"The job is running or completed","value":{"error":{"code":"validation_error","message":"Only pending, paused, failed, or cancelled jobs can be edited"}}},"commentContent":{"summary":"A comment edit that leaves no text and no media","value":{"error":{"code":"validation_error","message":"Write the comment text or add one image, GIF, or video"}}}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"429":{"description":"Too many requests. reddit_rate_limited: Reddit is limiting metadata requests. rate_limited: Queber is limiting requests. Wait for Retry-After (also error.retryAfterSeconds), then repeat the request with the same Idempotency-Key.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"reddit_rate_limited","message":"Reddit target analysis failed: Reddit is rate limiting requests. Try again in 30 seconds","retryable":true,"retryAfterSeconds":30}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"Reddit target analysis failed: fetch failed"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/cancel":{"post":{"operationId":"cancelJob","summary":"Cancel an automation job","description":"Cancels a pending or running local automation job. This changes local desktop state.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Cancelled job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"cancelled","source":"api","pause":"10-20","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/archive":{"post":{"operationId":"archiveJob","summary":"Archive an automation job","description":"Hides a completed, failed, or cancelled local automation job from the default queue view without deleting it. A pending, paused, or running job is refused with validation_error: cancel it first, because the queue runs a waiting job even from the archive.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Archived job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"completed","source":"api","pause":"10-20","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z","startedAt":"2026-08-12T09:40:56.000Z","completedAt":"2026-08-12T09:41:07.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1a2b3c4/we_shipped_scheduled_reddit_posting/","resultDescription":"Published text post in r/webdev","logs":[{"id":"1a2b3c4d-5e6f-4708-8192-a3b4c5d6e7f8","at":"2026-08-12T09:41:07.000Z","level":"success","title":"Post published","description":"Reddit accepted the post and returned a live URL.","stageId":"finished"}],"archivedAt":"2026-08-12T09:45:00.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/unarchive":{"post":{"operationId":"unarchiveJob","summary":"Bring an automation job back from the archive","description":"Returns an archived local automation job to the default queue view. A job that is not archived comes back unchanged. Needs Queber Desktop 1.2.11 or newer.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Job back in the queue view.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"completed","source":"api","pause":"10-20","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z","startedAt":"2026-08-12T09:40:56.000Z","completedAt":"2026-08-12T09:41:07.000Z","resultUrl":"https://www.reddit.com/r/webdev/comments/1a2b3c4/we_shipped_scheduled_reddit_posting/","resultDescription":"Published text post in r/webdev","logs":[{"id":"1a2b3c4d-5e6f-4708-8192-a3b4c5d6e7f8","at":"2026-08-12T09:41:07.000Z","level":"success","title":"Post published","description":"Reddit accepted the post and returned a live URL.","stageId":"finished"}]}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/delete":{"post":{"operationId":"deleteJob","summary":"Delete an automation job","description":"Permanently deletes a non-running local automation job from Queber Desktop history.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"usual":{"summary":"Usual call: empty body","value":{}},"chooseDesktop":{"summary":"After 409 desktop_selection_required","value":{"desktopId":"6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"}}}}}},"responses":{"200":{"description":"Deleted job marker.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean"}},"required":["id","deleted"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","deleted":true}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}},"/actions/jobs/{jobId}/retry":{"post":{"operationId":"retryJob","summary":"Retry an automation job","description":"Retries a failed, paused, or cancelled local automation job, now or at a future ISO datetime, optionally with another pause from the other posts of its profile.","security":[{"QueberApiToken":[]},{"QueberOAuth":["mcp:jobs:write"]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Queber automation job id.","example":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,200}$"},"description":"Retry key: 1-200 letters, digits, dots, underscores, colons, or dashes. A repeat with the same key returns the first result instead of acting twice. Use one key per job, never one per batch; reusing a key for a different request fails with 409 idempotency_key_reused.","example":"post-2026-08-13-r-webdev-01"},{"name":"X-Queber-Desktop-Wait-Ms","in":"header","required":false,"schema":{"type":"integer","minimum":0,"maximum":60000,"default":25000},"description":"Milliseconds to wait for a reconnecting Queber Desktop before answering 503 desktop_reconnecting (0-60000, default 25000). Keep your HTTP timeout above this wait plus 30 s for the desktop to answer.","example":10000}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledAt":{"type":"string","format":"date-time","description":"Optional future ISO datetime. Omit to queue now."},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause kept between this post and other posts of the same profile: off, or a range in minutes. Leave it out to keep the job's current pause. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"desktopId":{"type":"string","description":"Optional Queber Desktop id. Needed only after 409 desktop_selection_required, when this profile or job exists on several desktops (copied app data); pick one from error.desktops.","examples":["6b1f2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"]}},"additionalProperties":false},"examples":{"retryNow":{"summary":"Queue the retry now","value":{}},"retryLater":{"summary":"Retry at a future time with a longer pause","value":{"scheduledAt":"2026-08-13T07:00:00.000Z","pause":"30-60"}}}}}},"responses":{"201":{"description":"Retried job.","content":{"application/json":{"schema":{"type":"object","properties":{"job":{"type":"object","properties":{"id":{"type":"string"},"threadId":{"type":"string"},"desktop":{"type":"object","description":"Queber Desktop app that holds this item. Present when the desktop reports an installation id.","properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"profileId":{"type":"string"},"profileName":{"type":"string"},"profileProvider":{"type":"string","enum":["local","dolphin","adspower","gologin"],"description":"Browser provider of the profile that runs the job. Allowed values: local, dolphin, adspower, gologin."},"platform":{"type":"string","enum":["reddit","tiktok","instagram"],"description":"Allowed values: reddit, tiktok, instagram."},"automationType":{"type":"string","enum":["posting","comment","post_read"],"description":"Allowed values: posting, comment, post_read."},"status":{"type":"string","enum":["pending","running","paused","completed","failed","cancelled"],"description":"Current job state in the local queue. Allowed values: pending, running, paused, completed, failed, cancelled."},"source":{"type":"string","enum":["app","api","mcp"],"description":"Where the job was created: app (Queber Desktop), api (this API), or mcp (an MCP client). Missing on jobs created before Queber Desktop 1.2.9. Allowed values: app, api, mcp."},"attempts":{"type":"integer"},"platformData":{"type":"object","properties":{"reddit":{"type":"object","properties":{"posting":{"type":"object","properties":{"target":{"type":"string","description":"Reddit target, for example r/anime."},"title":{"type":"string"},"type":{"type":"string","enum":["text","image","video","link","media"],"description":"Use one allowedJobPostTypes value returned by analyzeSubreddit. Allowed values: text, image, video, link, media."},"body":{"type":"string"},"url":{"type":"string","description":"Required for link posts."},"media":{"type":"array","description":"Media items returned by importMedia. Required for image, video, or media posts.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"flairId":{"type":["string","null"],"description":"Reddit post flair id from analyzeSubreddit when flair is required. Prefer this over flairText."},"flairText":{"type":["string","null"],"description":"Optional flair text fallback. Queber resolves it only when it uniquely matches one analyzed flair; stored jobs keep flairId."},"tags":{"type":"array","description":"Optional Reddit post tags. Only tags reported as available by analyzeSubreddit are accepted. Allowed values: nsfw, spoiler, brand_affiliate.","items":{"type":"string","enum":["nsfw","spoiler","brand_affiliate"]}},"subredditMetadata":{"type":"object","description":"Optional target metadata returned by analyzeSubreddit.","additionalProperties":true}},"required":["target","title","type"],"additionalProperties":false},"post_read":{"type":"object","properties":{"links":{"type":"array","minItems":1,"description":"Reddit post links, read one after another in a background tab of the profile: permalinks, old.reddit, redd.it/<id>, /comments/<id>, profile posts (/user/<name>/comments/<id>), or share links (/r/<sub>/s/<code>). Repeats of one post are dropped; the plan limits links per run.","items":{"anyOf":[{"type":"string"},{"type":"object","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true}]}},"comments":{"description":"Also read the comments under each post; such a run is charged as 2 runs. true takes 100 per post, best first; an object sets limit (1-500) and sort. Up to 2 minutes a post; a run keeps at most 5,000 comments, later posts get none (stoppedBy run_limit).","anyOf":[{"type":"boolean"},{"type":"object","properties":{"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Comments per post, in the order Reddit shows them: a comment comes before its replies."},"sort":{"type":"string","enum":["best","top","new","old","controversial","qa"],"description":"Order Reddit loads comments in, as its sort menu names it; with a limit it decides which comments the read gets. best is Reddit's default. Allowed values: best, top, new, old, controversial, qa."}},"additionalProperties":false}]}},"required":["links"],"additionalProperties":false},"comment":{"type":"object","properties":{"link":{"type":"string","description":"Request only. The post (any form the post check takes), or a link to the comment to answer (/comments/<post>/comment/<id>/)."},"body":{"type":"string","description":"Text or HTML, as a post body, at most 10,000 characters. Plain text is typed like a person at any length (about 4 characters a second, so a long comment takes minutes); formatted text is pasted."},"media":{"type":"array","maxItems":1,"description":"One image, GIF, or video returned by importMedia, added after the text. The community decides which kinds its comments take; a run checks it before typing.","items":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","description":"Local file path on the connected Queber Desktop machine."},"type":{"type":"string","enum":["image","video"],"description":"Allowed values: image, video."},"name":{"type":"string"}},"required":["id","url","type","name"],"additionalProperties":false}},"replyToCommentId":{"type":"string","description":"Request only. Answer this comment (base-36 id, t1_ allowed): an id from checkRedditCommentTarget. Leave it out to comment on the post. Must match the comment a comment link names."},"post":{"type":"object","description":"Returned only: the post as parsed from link.","properties":{"url":{"type":"string"},"postId":{"type":"string"},"community":{"type":"string"}},"additionalProperties":true},"replyTo":{"type":"object","description":"Returned only: where the comment goes.","properties":{"kind":{"type":"string","enum":["post","comment"],"description":"post: a comment on the post; comment: a reply to commentId. Allowed values: post, comment."},"commentId":{"type":"string"}},"required":["kind"],"additionalProperties":true}},"additionalProperties":true}},"additionalProperties":false}},"additionalProperties":false},"resultData":{"type":"object","description":"Output of the last successful run, by automation, for example reddit.post_read of a Reddit post read. getJob lists its fields.","additionalProperties":true},"createdAt":{"type":"string","format":"date-time"},"scheduledAt":{"type":"string","format":"date-time","description":"When the job starts. A job created to run now may have none; it then starts at createdAt."},"requestedScheduledAt":{"type":"string","format":"date-time","description":"Start the creator asked for. Present only when the pause moved the start; scheduledAt then holds the real start."},"startMovedByPause":{"type":"boolean","description":"true when the profile pause moved the start; requestedScheduledAt then holds the requested time."},"pauseMove":{"type":"object","description":"Why the pause moved the start, as things stood when it was planned. Present only with startMovedByPause.","properties":{"near":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The other job of this profile and automation that was closer to the requested start than the pause minimum."},"after":{"type":"object","properties":{"at":{"type":"string","format":"date-time","description":"Its planned start, its finish when it had finished, or the planning time while it ran, rounded up to a whole minute."},"state":{"type":"string","enum":["scheduled","running","finished"],"description":"What the job was then: queued to start, running, or finished. Allowed values: scheduled, running, finished."},"jobId":{"type":"string"},"target":{"type":"string"}},"additionalProperties":true,"description":"The job the start was placed after, when more jobs stood in the way than near."},"gapMinutes":{"type":"integer","description":"Whole minutes between near and the requested start."},"pauseMinutes":{"type":"integer","description":"The pause picked for this job from its range, in minutes."}},"additionalProperties":true},"pause":{"type":"string","enum":["off","5-10","10-20","20-40","30-60"],"description":"Pause this job keeps between it and other posts of the same profile: off, or a range in minutes. Copied from the profile setting when the job was created, unless the request set it. Allowed values: off, 5-10, 10-20, 20-40, 30-60."},"startedAt":{"type":"string","format":"date-time","description":"When the current or last run started."},"completedAt":{"type":"string","format":"date-time"},"archivedAt":{"type":"string","format":"date-time"},"resultUrl":{"type":"string"},"resultDescription":{"type":"string"},"screenshotPath":{"type":"string"},"error":{"type":"string"},"pauseReason":{"type":"string","enum":["billing_limit_exhausted"],"description":"Why a paused job stopped. Allowed values: billing_limit_exhausted."},"i18nKey":{"type":"string"},"i18nParams":{"type":"object","additionalProperties":true},"logs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"level":{"type":"string","enum":["info","success","error","warning"],"description":"Progress event severity. Allowed values: info, success, error, warning."},"title":{"type":"string"},"description":{"type":"string"},"stageId":{"type":"string","description":"Automation stage the event belongs to."},"i18nKey":{"type":"string"}},"additionalProperties":true}}},"required":["id","profileId","platform","automationType","status","attempts","createdAt"],"additionalProperties":true}},"required":["job"]},"example":{"job":{"id":"9c8b7a65-4321-4f0e-9d8c-7b6a5f4e3d21","profileId":"3f1a2b4c-5d6e-4f70-8a91-b2c3d4e5f607","profileName":"Reddit main","profileProvider":"local","platform":"reddit","automationType":"posting","status":"pending","source":"api","pause":"30-60","attempts":1,"platformData":{"reddit":{"posting":{"target":"r/webdev","title":"We shipped scheduled Reddit posting from real browser profiles","type":"text","body":"Posts run through the local browser profile, so the account keeps its own session and fingerprint. Happy to answer questions.","flairId":null}}},"createdAt":"2026-08-12T09:40:55.000Z","scheduledAt":"2026-08-13T07:00:00.000Z"}}}}},"400":{"description":"Bad request. invalid_json: the body is not valid JSON. validation_error: a field is missing or malformed, or Queber Desktop refused the content or the job's state, or the Idempotency-Key header has invalid characters; error.message says which. Fix the request before sending it again.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_json","message":"Request body must be valid JSON"}}}}},"401":{"description":"Unauthorized. invalid_token: the bearer token is missing, expired, or revoked. Refresh the OAuth token or create a new API token.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"invalid_token","message":"Invalid access token"}}}}},"403":{"description":"Forbidden. insufficient_scope: the token lacks a scope this endpoint needs. mcp_paid_plan_required: the Queber plan does not include API access. user_blocked: the account is blocked.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"insufficient_scope","message":"Missing required scope: mcp:jobs:write"}}}}},"404":{"description":"Not found. not_found: the profile or job is not on any connected Queber Desktop. desktop_not_found: desktopId names no connected desktop; error.desktops lists the connected ones.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"not_found","message":"Job not found"}}}}},"409":{"description":"Conflict. desktop_selection_required: name a desktopId from error.desktops. desktop_multiple_sessions: close all but one older desktop app. idempotency_key_reused: the key was used for another request; send a new key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"desktops":{"type":"array","description":"Connected desktop apps; pass one id as desktopId.","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"appVersion":{"type":"string"}},"additionalProperties":true}},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"idempotency_key_reused","message":"This idempotency key was already used for a different request. Use a new key for a new request.","retryable":false}}}}},"413":{"description":"Payload too large. payload_too_large: the body is larger than the request limit. Pass large media as sourceUrl instead of inline data.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"payload_too_large","message":"Request body is larger than 110 MB. Pass large media as sourceUrl instead of inline data."}}}}},"426":{"description":"Update required. desktop_update_required: the connected Queber Desktop is older than the minimum supported version. Update the app, then repeat the request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_update_required","message":"Queber Desktop 1.2.8 on \"Office PC\" is outdated. Update Queber to version 1.2.9 or later to keep automations running."}}}}},"500":{"description":"Unexpected server error. Repeat the request later; contact Queber support if it keeps failing.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"action_error","message":"Internal server error"}}}}},"502":{"description":"Bad gateway. desktop_error: Queber Desktop failed the command, for example a browser provider that is not running or a media download that failed; error.message says why. desktop_busy: the app is busy; retry shortly.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_error","message":"database is locked"}}}}},"503":{"description":"Service unavailable. desktop_reconnecting: the app dropped and is expected back; wait for Retry-After, then repeat the request with the same Idempotency-Key, since the command may have run. desktop_offline: no desktop is connected; open Queber Desktop and sign in.","headers":{"Retry-After":{"description":"Seconds to wait before repeating the request. Sent when the wait is known.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."},"retryAfterSeconds":{"type":"integer","description":"Mirrors the Retry-After header."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_reconnecting","message":"Queber Desktop lost its connection and is reconnecting. Retry the request shortly; you do not need to restart the app.","retryable":true,"retryAfterSeconds":12}}}}},"504":{"description":"Gateway timeout. desktop_timeout: Queber Desktop did not answer in time. The command may still finish; repeat the request with the same Idempotency-Key to get its result.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean","description":"True when the same request can succeed later unchanged."}},"required":["code","message"],"additionalProperties":true}},"required":["error"]},"example":{"error":{"code":"desktop_timeout","message":"Queber Desktop did not respond in time","retryable":true}}}}}}}}},"components":{"schemas":{},"securitySchemes":{"QueberOAuth":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://mcp.queber.app/oauth/authorize","tokenUrl":"https://mcp.queber.app/oauth/token","scopes":{"mcp:account:read":"Read Queber account information","mcp:account:write":"Disconnect this AI integration from Queber","mcp:status:read":"Read Queber Desktop connection status","mcp:targets:read":"Validate social targets before creating jobs","mcp:media:write":"Import local media for automation jobs","mcp:profiles:read":"Read local browser profiles","mcp:jobs:read":"Read local automation jobs","mcp:jobs:write":"Create, cancel, and retry local jobs","mcp:automation:run":"Run supported local automation workflows"}}}},"QueberApiToken":{"type":"http","scheme":"bearer","bearerFormat":"Queber API token"}}}}