Skip to content

OAuth v2 workflows

Terminal window
npm install --global @anakonn/ankk@0.5.1
ankk --version

ANKK v2 uses your user account through browser OAuth. Your existing permissions apply to every request. Connecting an app does not grant extra brand permissions. Choose a brand when working; OAuth authorization does not select a brand.

Use CLI 0.5.1 with Node.js 24 or newer. The public client ID below identifies ANKK CLI; it is not a secret.

Terminal window
export ANKK_OAUTH_CLIENT_ID=ankk-cli-production
Terminal window
ankk --json auth login --environment production
ankk auth status --environment production --connection OAUTH_CONNECTION_ID
ankk --json brands list --environment production --connection OAUTH_CONNECTION_ID --all
ankk --json connections list --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --all

Replace uppercase identifiers with IDs returned by your own requests. The OAuth connection ID selects your login. An SNS account ID identifies a posting target; it is different from both the OAuth connection and the provider’s account ID. Use the same environment and brand throughout a workflow. These examples specify both explicitly even when you have configured a local brand default.

For a terminal without an automatically opened browser, use ankk auth login --environment production --device --no-open and follow the displayed verification instructions. Tokens are stored in the OS credential store. If that store is unavailable, restore it before signing in; never paste tokens into a chat or save them in a publication JSON file.

Terminal window
ankk --json analytics get --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --from 2026-10-01T00:00:00Z --to 2026-10-02T00:00:00Z
ankk --json posts list --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --all

Choose the actual reporting period. The start is inclusive and the end exclusive; timestamps use UTC. Translate the user’s local dates into UTC before querying. Add --sns-account SNS_ACCOUNT_ID to limit the result to one account.

The result describes stored observations. Check coverage and observation times before comparing periods. Missing data is not zero. A latest account snapshot has its own measurement time and is not necessarily a period total. Instagram exact period insights are separate from accumulated observations. A read does not start provider collection. posts refresh is a separate action for post/comment data, not a request to refresh analytics.

Lists use cursors. --all follows pages; data can change while paging, so the result is not a snapshot. If a cursor expires, report the incomplete result and start a new listing deliberately rather than combining it silently with the old pages.

Terminal window
ankk --json media create-upload --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --file ./photo.jpg --idempotency-key UPLOAD_KEY
ankk --json media complete-upload MEDIA_ID --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --idempotency-key INSPECTION_KEY --wait --wait-timeout 180
ankk --json media get MEDIA_ID --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID

The first command registers and transfers the file. Save its media ID even if the transfer fails or the reply is uncertain. The second requests inspection; use the media only when the final media status is ready. These steps do not publish. Media can be reused within its brand. Upload separately for another brand.

If only the upload URL expires, use media refresh-upload MEDIA_ID with the same environment, login and brand. The new URL does not extend the original business deadline or replace the file. Different bytes require a new media upload. Treat signed transfer URLs as credentials and keep them out of shared transcripts. Clients without file transfer can use the returned browser progress URL, sign in and select the file, then return with the same media ID and check readiness.

Confirm the brand, accounts, full text, ordered thread segments, attachments, provider options and execution time before publishing AI-prepared content. Existing approval for the exact intent is sufficient. A request to analyze or draft content alone is not publication approval.

Save this minimal immediate-publication input as publish.json. Select an account that supports the proposed text-and-image combination; the server checks current capability, media readiness and permission again.

{
"scheduled_at": null,
"targets": [
{
"sns_account_id": "SNS_ACCOUNT_ID",
"text": "The exact text you approved",
"media_ids": ["MEDIA_ID"]
}
]
}
Terminal window
ankk --json contents publish --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --file publish.json --idempotency-key PUBLICATION_KEY

Choose and retain a unique key for this intent before sending. Reuse that exact key and payload after an uncertain response, including when moving between API, CLI and MCP. Do not create another publication just because a connection timed out. The same key with changed input is a conflict. An expired key does not create new work: inspect the old outcome before deliberately starting a new intent.

For a reservation, replace scheduled_at: null with the approved future UTC time, for example 2026-12-01T09:00:00Z. Replace this illustrative date before use and verify it is still in the future. A completed registration returns a separate publish_operation_id; it does not mean the scheduled SNS posts are published.

Terminal window
ankk --json operations get OPERATION_ID --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --wait --wait-timeout 180

For immediate publication, follow the returned operation ID. For a reservation, follow publish_operation_id at execution time. Waiting is optional and local. CLI exit 10 means the wait limit expired; exit 130 means waiting was interrupted. Neither cancels the server task. Continue reading the same operation. Exit 11 from waiting indicates a failed, canceled or partially successful final outcome; inspect the per-account results. A normal status lookup can exit 0 while reporting a failed operation, so scripts must inspect the response status too.

Report each account separately. Preserve successful posts and their URLs. The ordered posts array contains the confirmed posts of a thread; representative post_url alone may not describe the whole thread. An absent URL or unresolved status is not proof that the provider created nothing. Keep reconciling and unknown outcomes unresolved until the existing task supplies evidence.

Read contents get CONTENT_ID with the same environment, login and brand before changing content or time. Pass its current version as --expected-version. contents update edits eligible unstarted targets; contents reschedule changes their UTC schedule. A version conflict requires a new read and review, not a silent overwrite. contents cancel requests cancellation; inspect the returned publication operation until cancellation is confirmed. Execution may win the race.

Retry only selected failed accounts currently marked can_retry:

Terminal window
ankk --json contents retry ORIGINAL_OPERATION_ID --environment production --connection OAUTH_CONNECTION_ID --brand BRAND_ID --accounts FAILED_SNS_ACCOUNT_ID --idempotency-key RETRY_KEY

This is a new execution intent and needs an appropriate new key and user approval unless already covered. Keep that retry key after an uncertain response. Retry uses stored content and executes as soon as possible; it never republishes successful or uncertain targets. For a new future reservation, contents duplicate returns editable input only. Review it and submit a new approved publication.

Discarding eligible failed queue entries hides them from the work queue; it does not delete posts, erase execution history or retry anything. Bulk cancellation can return accepted and rejected groups together; follow each accepted publication operation. Bulk discard completes synchronously: inspect the receipt’s discarded and rejected groups, without waiting for a new operation. In both cases, read the complete receipt instead of treating an exit code as an all-or-nothing result.

Read the structured error code, request ID, operation ID when available, next_action and retry_at. Authentication recovery returns to the original operation. Permission errors require legitimate access, not a different interface. Rate limits and capability restrictions must be respected. A retryable request does not authorize a new publication or replacement key.

Terminal window
ankk auth logout --environment production --connection OAUTH_CONNECTION_ID

Logout reports server revocation separately from local credential removal. If server revocation is unconfirmed, revoke the old connection from ANKK settings or another valid connection. Removing an OAuth connection does not cancel already accepted publications or delete brand-owned media.

MCP uses user OAuth at https://api.ankk.app/mcp/v2. Your host needs a registered client; an endpoint URL alone does not complete setup. Official ChatGPT and Claude directory listings are not available. Use text and structured results when cards are unavailable; verify analytics values and observation times rather than relying only on the conversational summary.

Skills provide procedures, not permissions or credentials. Install the pinned release candidate below. Verify the selected brand, approval and final operation result.

Terminal window
npx skills add https://github.com/Anakonn/ankk-skills/tree/v0.1.0-rc.1 --skill ankk-analyze --skill ankk-publish