Getting Started

OpenAPI, SDKs, CLI & MCP

Use TokPortal OpenAPI files, the public Node SDK, CLI, and MCP server.

OpenAPI, SDKs, CLI & MCP

TokPortal exposes public developer tools from the same API schema used for the OpenAPI spec, generated API reference, LLM assets, CLI, SDK, MCP server, and webhook helpers. All packages are open source under the tokportal GitHub organization.

Distribution Matrix

SurfaceDistributionInstall / usageSourceStatus
OpenAPIPublic docs/openapi.json or /openapi.yamlPublic source of truth
Node / TypeScript SDKnpmnpm install @tokportal/nodetokportal-nodePublic package
CLInpmnpm install -g @tokportal/clitokportal-cliPublic package
MCP servernpm / remotenpx tokportal-mcp · https://app.tokportal.com/api/ext/mcptokportal-mcpPublic package
Python SDKPyPIpip install tokportaltokportal-pythonSee release manifest
Go SDKGo modulego get github.com/tokportal/tokportal-gotokportal-goSee release manifest
ExamplesGitHubclone and runexamples
Postman collectionPostmanRun in Postman · JSONexamples/postmanPublic collection (91 requests, auth preset)
n8n community nodenpmSettings → Community Nodes → n8n-nodes-tokportaln8n-nodes-tokportalPublic package
LangChain / CrewAIPyPIpip install langchain-tokportal · pip install crewai-tokportallangchain-tokportal · crewai-tokportalPublic packages
Activepieces piecenpmSettings → Pieces → Install @tokportal/piece-tokportalactivepieces-piece-tokportalPublic package
ZapierZapierInvite link (beta)zapier-tokportalPrivate beta

The Python and Go clients are generated from the same OpenAPI schema and are published (see the package release manifest for exact versions). Ruby, Java, PHP, .NET, and Rust SDKs remain deferred — use the raw HTTP API or the MCP server from any language.

Node / TypeScript SDK

Install:

npm install @tokportal/node

Create a client:



const tokportal = new TokPortal({
  apiKey: process.env.TOKPORTAL_API_KEY!,
});

Create a bundle, configure webhooks, export analytics, and use media upload helpers:

const bundle = await tokportal.bundles.create({
  bundle_type: "account_and_videos",
  country: "USA",
  videos_quantity: 5,
});

const webhook = await tokportal.webhooks.create({
  url: "https://example.com/tokportal/webhook",
  events: ["bundle.created", "bundle.published"],
});

const csv = await tokportal.analytics.exportVideos({
  account: ["9f3a7b2e-1c4d-4e8f-a5b6-7d9e0f1a2b3c"],
});

const image = await tokportal.uploads.imageFromUrl({
  url: "https://cdn.example.com/photo.jpg",
  bundle_id: bundle.data.id,
  purpose: "carousel",
});

await tokportal.bundles.fixVideoDownload(bundle.data.id, 1, {
  video_url: "https://cdn.example.com/replacement.mp4",
});

console.log(bundle.data.id, webhook.data.id, csv, image.data.id);

Direct multipart uploads can use either a Blob or a local file path:

const uploaded = await tokportal.uploads.videoDirectFile(
  "./video.mp4",
  bundle.data.id,
  "video/mp4",
  { idempotencyKey: "video-upload-123" },
);

console.log(uploaded.data.url);

Coverage and irreversible account access

The SDK exposes the complete account-level Coverage flow. Always read a fresh quote before reactivation. A quote of 0 credits is valid and still requires the explicit call that resumes work:

const coverage = await tokportal.accounts.coverage(accountId);
const quote = coverage.data.reactivation_quote;

if (quote) {
  await tokportal.accounts.reactivateCoverage(
    accountId,
    {
      expected_credits: quote.credits,
      expected_current_period_end: quote.current_period_end,
      expected_lock_version: quote.lock_version,
    },
    { idempotencyKey: `coverage-reactivate-${accountId}-${quote.lock_version}` },
  );
}

Credential reveal and verification-code access use the same two-step policy flow. The preview call has no body and returns HTTP 428 without revealing, debiting, or detaching anything. Display the complete disclosure and acknowledgment from the error. Only after explicit account-owner confirmation should you retry with the exact policy version:

try {
  await tokportal.accounts.revealCredentials(accountId);
} catch (error) {
  if (!(error instanceof TokPortalApiError) || error.status !== 428) throw error;

  const policyVersion = String(error.details?.policy_version);
  const result = await tokportal.accounts.revealCredentials(
    accountId,
    {
      acknowledge_support_forfeit: true,
      policy_version: policyVersion,
    },
  );
  console.log(result.data);
}

Use verificationCode with the same arguments when retrieving a code. A successful first code retrieval is equivalent to credential reveal and can permanently detach the account.

Every OpenAPI operation is also reachable through the generated operation map:

const retry = await tokportal.requestOperation("retryWebhookDelivery", {
  path: {
    id: webhook.data.id,
    delivery_id: "7a1f3e5d-2222-4333-9444-abc123abc123",
  },
});

Webhook Signatures

Use the SDK helper with the exact raw request body received by your HTTP framework, before JSON parsing or re-serialization:



const valid = verifyWebhookSignature(
  rawBody,
  request.headers["tokportal-signature"],
  process.env.TOKPORTAL_WEBHOOK_SECRET!,
);

See Webhooks for the full event catalog, endpoint management API, manual HMAC verification examples, delivery logs, and retry behavior.

CLI

Install:

npm install -g @tokportal/cli

Use:

export TOKPORTAL_API_KEY=sk_your_key_here

tokportal get-current-user
tokportal list-bundles --page 1 --per_page 25
tokportal create-bundle --body '{"bundle_type":"account_and_videos","country":"USA","videos_quantity":5}'
tokportal upload-video-direct --file ./video.mp4 --bundle_id 00000000-0000-0000-0000-000000000000

Coverage and credential policy flow:

# Read Coverage and its latest reactivation quote.
tokportal get-account-managed-subscription --id "$ACCOUNT_ID"

# Confirm the exact snapshot returned by the GET request.
tokportal reactivate-account-managed-subscription \
  --id "$ACCOUNT_ID" \
  --idempotency-key "coverage-reactivate-$ACCOUNT_ID-v4" \
  --body '{"expected_credits":0,"expected_current_period_end":"2026-09-09T11:00:00.000Z","expected_lock_version":4}'

# Policy preview: no --body is expected. HTTP 428 returns the current terms.
tokportal reveal-account-credentials --id "$ACCOUNT_ID"

# Accepted reveal after displaying the server-provided terms.
tokportal reveal-account-credentials \
  --id "$ACCOUNT_ID" \
  --body '{"acknowledge_support_forfeit":true,"policy_version":"VERSION_RETURNED_BY_428"}'

retrieve-account-verification-code uses the same optional preview body and accepted body. Do not script the accepted form without an explicit user confirmation step. Do not pass --idempotency-key to either secret-returning command. If the server returns CREDENTIAL_REVEAL_QUOTE_CHANGED, fetch the no-body preview again and obtain fresh confirmation.

Multipart upload commands are generated from OpenAPI too. Use --file <path> for the binary field and pass form fields such as --bundle_id or --auto_publish as regular flags.

Failed CLI commands print the original API payload plus diagnostics:

{
  "payload": {
    "error": {
      "code": "RATE_LIMIT_EXCEEDED",
      "message": "Rate limit exceeded."
    }
  },
  "diagnostics": {
    "request_id": "req_...",
    "retry_after_seconds": 1,
    "rate_limit": {
      "limit": 120,
      "remaining": 0,
      "reset": 1779724800
    }
  }
}

Structured Errors

The Node SDK exposes structured API errors with the HTTP status, TokPortal error code, details, X-TokPortal-Request-ID, Retry-After, rate limit metadata, and a retryability helper.



try {
  await tokportal.bundles.create({
    bundle_type: "account_and_videos",
    country: "USA",
    videos_quantity: 5,
  });
} catch (error) {
  if (error instanceof TokPortalApiError) {
    console.log(error.status, error.code, error.details, error.requestId);
    if (error.retryable) {
      const waitMs = (error.retryAfterSeconds ?? 1) * 1000;
      // Retry with backoff.
    }
    console.log(error.rateLimit?.remaining, error.rateLimit?.reset);
  }
}

Idempotency Keys

Use idempotency keys for mutating requests you may retry after network failures. TokPortal replays a durably completed response for 24 hours when the key and request fingerprint match. A claim that remains processing does not auto-expire: retry the exact request briefly, then stop and request support/operator reconciliation if IDEMPOTENCY_KEY_IN_PROGRESS persists. Never switch to a new key for the uncertain mutation.

await tokportal.bundles.create(
  {
    bundle_type: "account_and_videos",
    country: "USA",
    videos_quantity: 5,
  },
  { idempotencyKey: "bundle-create-123" },
);

Client Identification

The public Node SDK, CLI, and MCP server send X-TokPortal-Client on API requests. This does not affect API behavior; it helps TokPortal support and observability identify the integration surface and version.

SurfaceHeader
Node / TypeScript SDKX-TokPortal-Client: tokportal-node/0.1.1
CLIX-TokPortal-Client: tokportal-cli/0.1.2
MCP serverX-TokPortal-Client: tokportal-mcp/1.15.0

MCP

Full per-host install guide (Claude, Claude Code, Cursor, VS Code, ChatGPT, Codex, Gemini CLI, Windsurf, Cline, Goose, Zed, JetBrains, n8n…): MCP Server. Source: github.com/tokportal/tokportal-mcp.

npx tokportal-mcp

The local and remote MCP catalogs expose these account tools:

  • tokportal_get_account_managed_subscription
  • tokportal_reactivate_account_managed_subscription
  • tokportal_cancel_account_managed_subscription
  • tokportal_reveal_account_credentials
  • tokportal_retrieve_account_verification_code

For the last two tools, omit body to obtain the policy preview. After the human has reviewed and accepted the returned terms, call the same tool with body.acknowledge_support_forfeit: true and the exact body.policy_version. Do not send idempotency_key: these tools can return secrets and reject it before execution. Agents must never infer consent from the existence of a credential request or silently fill the acceptance body. If the price or policy changes, stop on CREDENTIAL_REVEAL_QUOTE_CHANGED, fetch the new preview, show it to the human, and request fresh confirmation.

Failed MCP tool calls return an error result containing the original API payload plus diagnostics.request_id, diagnostics.retry_after_seconds, and diagnostics.rate_limit when available.

{
  "mcpServers": {
    "tokportal": {
      "command": "tokportal-mcp",
      "env": {
        "TOKPORTAL_API_KEY": "sk_your_key_here"
      }
    }
  }
}

Schema Source

Generated Surface Verification

TokPortal keeps the public Node SDK, CLI, MCP tools, OpenAPI, and LLM assets aligned with one verification command:

npm run verify:developer-surface

The command rebuilds the public npm packages, regenerates CLI/MCP definitions, checks the public OpenAPI operation count, and rebuilds the docs AI assets when the docs repo is present.

To prepare package repository exports locally:

npm run export:developer-packages

This writes dist/developer-packages/tokportal-node, tokportal-cli, and tokportal-mcp from the package release manifest. Each export includes .tokportal-release.json with the target repo, build command, publish command, schema source, generated .github/workflows/ci.yml / .github/workflows/release.yml, plus SECURITY.md, CONTRIBUTING.md, RELEASE.md, and LICENSE.