Documentation

Intigin gateway reference

Public reference for the per-embed HTTP API, plan capabilities, and how the dashboard fits in. Gateway base for examples: https://intigin.com

Overview

Visitors load your protection bundle from …/YOURTOKEN.js. The bundle can poll for configuration updates and, when enabled, the embed HTTP API (/api/embed-console/v1/*) for remote JavaScript execution on tabs that loaded that bundle.

One Gateway API key (iga_… from the dashboard) authenticates REST (/api/v1/…) and the embed queue (/api/embed-console/v1/queue) with Authorization: Bearer. Account-scoped routes avoid embed ids when you have a single embed. See Gateway API.

The logged-in dashboard remains the primary UI for interactive edits — and is itself a client of the API documented below.

Chained scoped API keys

The Gateway API uses scope-aware keys. Every embed, every account, and every group can each mint their own iga_… key. The hierarchy is implicit: a higher-scope key already authorizes everything below it, so you almost never need to mint a per-resource key just to control resources you already own.

flowchart TD
    AccountKey["Account key (account/aid)"]
    GroupKey["Group key (group/gid)"]
    EmbedKey["Embed key (embed/eid)"]

    AccountKey --> GroupKey
    AccountKey --> EmbedKey
    GroupKey  --> EmbedKey

Why per-resource keys exist at all. They're for explicit delegation — handing a single embed to a contractor, or a single group to a partner, without exposing the parent key. On the embed dashboard, the Embed API key is primary; the full account key lives under Advanced when you need one secret for every embed. Group delegation stays under Advanced on the Groups page.

Worked examples by tier

Tycoon (multi-embed account, no groups). On Dashboard → Settings with an embed selected, the primary Embed API key targets that embed; expand Advanced — Account API key for one secret that controls every embed. Target a specific embed by URL:

# One key, any embed under your account
curl -H "Authorization: Bearer iga_ACCOUNT…" \
  -X POST https://intigin.com/api/v1/embeds/EMBED_HEX/disable

# Same key on the account namespace (manage account itself, not just embeds)
curl -H "Authorization: Bearer iga_ACCOUNT…" \
  https://intigin.com/api/v1/accounts/ACCOUNT_HEX/embeds

Team owner (groups + members + embeds). The same account key (Team owner API key) covers every group in the team, every member account in those groups, and every embed those members own or that the group has been assigned. You almost never need a per-group or per-member key.

# Disable an embed in any of your groups
curl -H "Authorization: Bearer iga_OWNER…" \
  -X POST https://intigin.com/api/v1/embeds/EMBED_HEX/disable

# Change a member's status (suspend/ice/active)
curl -H "Authorization: Bearer iga_OWNER…" \
  -X POST https://intigin.com/api/v1/accounts/MEMBER_HEX/status \
  -d '{"status":"iced"}' -H "Content-Type: application/json"

# Assign an existing embed to one of your groups
curl -H "Authorization: Bearer iga_OWNER…" \
  -X POST https://intigin.com/api/v1/groups/GROUP_HEX/embed/assign \
  -d '{"embed_id":"EMBED_HEX"}' -H "Content-Type: application/json"

Where to find each key in the dashboard

  • Embed key — With an embed selected: Dashboard → Settings → Embed console & API keys → primary Embed API key (scoped to that embed). Open an embed from /app/embeds first if you use multiple embeds.
  • Account key — Same screen: Advanced — Account API key (all embeds), or the primary card on /app/embeds, /app/groups, and /app/accounts for team owners. Mintable whenever your plan includes Gateway API access (Free+).
  • Group key/app/groups → expand a group → Advanced — group delegation key. Visible to enterprise owner / group_admin; requires the group_management entitlement.

Authorization is enforced by a single resolver (intigin_scope_can_act_on(actor, target_type, target_id)). Cross-scope attempts return 403 forbidden. Regenerating any key invalidates the previous one immediately — no rotation window. The plaintext is shown once on mint; the server only stores password_hash(). Lose it → regenerate again.

The Authentication block under Gateway API recaps the same model with the per-scope endpoint table and the rules for X-Intigin-Embed-Id when an account / group key needs to disambiguate.

Embed HTTP API

Base path: https://intigin.com/api/embed-console/v1/…. Requires browser_console_api on the billing account (see Plans — enabled from Free upward).

Enable / disable

New embeds start with the remote queue off. Turning it on (dashboard or via POST /api/v1/account/embed-console / POST …/embeds/<id>/embed-console) also tries to enable Live Block Updates where your plan allows, and forces the visitor live poll interval to 1 second on that embed so pushes stay responsive.

When disabled, POST …/queue returns 403 immediately — no queued execution. The visitor unified poll (GET …/api/v1/embed/<script_token>/poll) keeps running with Live Block Updates; it simply never includes a js field until the API is enabled again and your plan includes browser_console_api.

Security: arbitrary JavaScript

Queued scripts run in your visitors’ browsers (same origin as the page loading your embed). Anyone who can enqueue JavaScript can execute arbitrary code in that context — treat the Gateway API key like root access to your site’s client-side behavior. Prefer server-side calls; never expose iga_… in public pages.

Authentication

All POST embed-console endpoints require Authorization: Bearer <iga_…> — the same Gateway API key as REST. With multiple embeds, add X-Intigin-Embed-Id (lowercase hex embed id, typically 16 characters). The public 32-character hex script token from your embed URL is only for unauthenticated GET …/api/v1/embed/<script_token>/poll (same token as in …/TOKEN.js).

When calling from DevTools on another origin, use the full gateway URL (this site’s home_url()), not a path-only /api/… (that would hit the wrong host).

Queue — POST …/queue

JSON body: {"js":"…"} or {"javascript":"…"}. Max length per item: 65536 characters. Jobs are stored in a FIFO per embed (max 50 pending). Queue full → 507 without dropping older jobs. The visitor bundle evaluates returned JS with eval-equivalent behavior — only queue code you fully trust.

Unified visitor poll — GET …/api/v1/embed/<script_token>/poll

Unauthenticated. <script_token> is the same 32-character hex token as in https://…/TOKEN.js. When Live Block Updates is enabled in the visitor bundle, its poller calls this endpoint on your embed’s poll interval; on Free you can still call the same URL programmatically (e.g. every 1s) without that bundle block. Query string: ?v=<known_bundle_version>&qrev=<known_queue_rev> (and &ig_test=… for test tabs).

Response is JSON: {"v":1217,"qrev":4} and, when the queue has a job and your plan + embed allow it, "js":"…" with one dequeued script. 304 Not Modified when v and qrev already match the server and the queue is empty — idle tabs avoid downloading a body. ETag is "v.qrev" (e.g. "1217.4"). Without browser_console_api or with the embed console API off, qrev stays 0 and no js field is returned; the bundle still receives fresh v for live updates.

run-local — POST …/run-local

Requires Bearer secret. Body: {"javascript":"…"}. Responds {"ok":true}. Execution is still in the browser context that invokes it (e.g. DevTools).

Errors

  • 401 — missing or wrong secret
  • 403 — embed HTTP API disabled, plan lacks console API (on POST embed-console routes such as queue), billing account iced / suspended, or (Free) poll faster than the server minimum spacing
  • 507 — queue full
  • 400 — invalid body / payload too large

Code examples

Replace YOUR_IGA_TOKEN (Gateway key iga_…) and SCRIPT_TOKEN. Gateway root is output from WordPress — copy again after changing Site Address.

JavaScript (fetch)

const GATEWAY = "https:\/\/intigin.com";
const QUEUE_URL = GATEWAY + '/api/embed-console/v1/queue';
const TOKEN = 'YOUR_IGA_TOKEN';

fetch(QUEUE_URL, {
  method: 'POST',
  credentials: 'omit',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + TOKEN,
  },
  body: JSON.stringify({ js: "console.log('Hello from Intigin queue');" })
}).then(r => r.json()).then(console.log);

Python (requests)

import requests

GATEWAY = "https:\/\/intigin.com"QUEUE_URL = f"{GATEWAY}/api/embed-console/v1/queue"
TOKEN = "YOUR_IGA_TOKEN"

r = requests.post(
    QUEUE_URL,
    headers={"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"},
    json={"js": "console.log('hello')"},
    timeout=30,
)
print(r.status_code, r.text)

Node.js (fetch)

const GATEWAY = "https:\/\/intigin.com";
const QUEUE_URL = `${GATEWAY}/api/embed-console/v1/queue`;
const TOKEN = 'YOUR_IGA_TOKEN';

const res = await fetch(QUEUE_URL, {
  method: 'POST',
  credentials: 'omit',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${TOKEN}`,
  },
  body: JSON.stringify({ js: "console.log('hello');" }),
});
console.log(res.status, await res.text());

PowerShell

$Gateway = "https:\/\/intigin.com"$Token = "YOUR_IGA_TOKEN"
$body = '{"js":"console.log(1)"}'
Invoke-RestMethod -Uri "$Gateway/api/embed-console/v1/queue" -Method Post `
  -Headers @{ Authorization = "Bearer $Token"; "Content-Type" = "application/json" } -Body $body

Go (net/http)

package main

import (
  "bytes"
  "net/http"
  "os"
)

func main() {
  gateway := "https:\/\/intigin.com"  req, _ := http.NewRequest(http.MethodPost, gateway+"/api/embed-console/v1/queue",
    bytes.NewReader([]byte(`{"js":"console.log(1)"}`)))
  req.Header.Set("Authorization", "Bearer "+os.Getenv("INTIGIN_GATEWAY_KEY"))
  req.Header.Set("Content-Type", "application/json")
  resp, err := http.DefaultClient.Do(req)
  if err != nil { panic(err) }
  defer resp.Body.Close()
}

cURL

curl -sS -X POST 'https://intigin.com/api/embed-console/v1/queue' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_IGA_TOKEN' \
  -d '{"js":"console.log(1)"}'

Unified poll URL shape

https://intigin.com/api/v1/embed/SCRIPT_TOKEN/poll

Plans & limits

Matrix from Intigin_Entitlements::base_plan(). means unlimited (null limit).

Feature Free Live Studio Tycoon Team
Custom blocks (max) 1 25
Embeds (max) 1 1 1
Groups (max) 0 0 0 0
Group members (max) 0 0 0 0
Static JS blocks
Live block updates
Live inline custom code
Custom poll interval
Test mode
Push test → production
Embed HTTP API (queue + unified visitor poll)
Multiple embeds
Groups & org

Request budget (7-day rolling)

Each billing account has a 7-day rolling cap starting from your account's first usage day, plus optional grant balance (extra requests). The window rolls forward every 7 days from that anchor — no calendar dependency or UTC cutover. Usage counts:

  • Each GET …/TOKEN.js that serves a body or 304 (conditional reload).
  • Each GET …/api/v1/embed/<script_token>/poll, including 304.
  • Successful authenticated /api/v1/… automation traffic that resolves to embed or account state after Bearer auth (failed auth / obvious 404s are not billed the same way).

Default caps by tier (before overrides and before any global admin edits in /app/admin/settings): Free 86,000/week, Live 86,000,000, Studio 86,000,000,000, Tycoon 86,000,000,000,000, Team 86,000,000,000,000,000 (each step ×1000 from Free). The live site uses whatever caps the global admin has configured.

Top-ups. In the dashboard, use Add credits: enter an amount in USD and we credit requests at $1 ≈ 86,000 requests (preview / ops — no card checkout wired yet). The bar refreshes automatically on an interval while the tab is open.

Team attribution. If an embed id appears in any team group’s embed_ids for an enterprise, traffic for that embed bills the enterprise (team owner) account pool, not only embeds owned by that user.

Over cap. When usage reaches the cap, the billing account is set to iced with ice_reason = quota. Public .js, unified poll, embed-console, and Gateway API for that billing context return 403 until the week resets (auto-unfreeze for quota-only ice) or you add grant balance / an admin adjusts caps. Manual iced with another reason is not cleared by the weekly job.

Free poll floor. The same public poll URL may enforce a minimum interval (1s) between responses per token to match the product default.

Full HTML replacement

The standard integration adds the protection script to your site's <head>. But you can also replace your entire HTML file with a minimal document that contains nothing except the Intigin snippet. Because the bundle executes all enabled blocks — HTML, CSS, and JavaScript — those blocks collectively become the complete page.

When to use this

  • Hard redirect / access gate pages — Replace a static index.html on a CDN or object store. Visitors see only what your blocks produce; there is no underlying page to leak through.
  • Serverless or edge deployments — A single-file origin with no backend. Intigin evaluates the visitor, injects whatever blocks are enabled, and nothing else is served.
  • Decoy / honeypot pages — Publish a realistic-looking URL entirely controlled by your block configuration, with no real content behind it.
  • Minimal landing pages driven by custom blocks — Build the full UI across one or more Custom Blocks (HTML, CSS, JS) and serve it from a bare document.

The replacement template

Copy this as your complete HTML file. Swap in your embed script URL from the Embeds panel in the dashboard:

<!DOCTYPE html>
<html lang="en">
<!-- BEGIN Intigin — Frontend Access Control -->
<script src="https://your-domain/your-embed-token.js"></script>
<noscript><meta http-equiv="refresh" content="1;url=about:blank"></noscript>
<!-- END Intigin -->
</html>

The <noscript> redirect is optional but recommended — it sends visitors with JavaScript disabled to about:blank rather than a blank page.

How blocks render in this mode

All three custom block types work in full-replacement mode:

  • HTML blocks — Injected directly into the document as rendered markup. Because there is no other body content, the block's HTML is the page. Stack multiple HTML blocks and they are appended in order.
  • CSS blocks — Injected as an inline <style> element. Use these to style the HTML blocks above — fonts, layout, colours, animations — without shipping a separate stylesheet.
  • JavaScript blocks — Injected as an inline <script> element and execute immediately. Wire up event listeners, fetch data, run redirect logic, or manipulate anything the HTML blocks produced.

A common pattern is one HTML block for structure, one CSS block for styling, and one JS block for behaviour — a complete single-page application served entirely from your Intigin bundle with no other files.

Live Updates

Full HTML replacement works with Live Block Updates. The embed script polls for bundle changes on your configured interval and hot-swaps block content without a page reload — toggle a block or push an edit in the dashboard and it appears on all active sessions within one poll cycle.

Dashboard workflows (session)

Interactive editing uses a browser session at https://intigin.com/app/login. The same capabilities are available via the Gateway API (one Bearer key; account routes when you have a single embed).

  • Toggle blocks — On /app, enable or disable protection blocks; changes bump bundle version for visitors.
  • Custom blocks — Create, edit, and delete user-defined blocks via dashboard forms and XHR to /app/account/… routes.
  • Rename an embed — On /app/embeds, use the inline rename form per embed row. POST to /app/embeds/{eid}/label or via the Gateway API at POST /api/v1/embeds/{eid}/label.
  • Poll intervalFree uses a fixed 1000ms API-facing interval; Live+ can choose from the full poll options where custom_poll_interval applies. Pairs with Live Block Updates in the visitor bundle when that feature is on for your tier.
  • Live Edit / live updates — Edits from the dashboard apply to visitor bundles as version changes; visitors pick them up via the live-updates poller or reload behavior.
  • Test mode — Preview test configuration with ?ig_test=… where enabled.
  • Push test → production — Promote test configuration when your tier allows.
  • Remote queue — Per-embed toggle on the Embed console & API keys card (Settings tab, embed selected).
  • API keys — Embed-scoped key on that card for REST + queue on the current embed; account key under Advanced for all embeds. See docs. Keys can be regenerated (rotates to a new token) or revoked (removes the key without issuing a replacement). See API key lifecycle.
  • Multiple embeds / groups/app/embeds, /app/groups, etc., when entitlements allow.

API key lifecycle — regenerate vs revoke

Each resource scope (embed, account, group) carries one active iga_… key. Two mutation paths exist:

ActionEffectNew key issued?
Regenerate Mints a new token, hashes it, and invalidates the old one immediately. The new plaintext is shown exactly once — copy it before navigating away. Yes — shown once
Revoke Deletes the hash and removes the token from the lookup map. All callers using that key receive 401 Unauthorized from this point. No replacement key is issued. No

Both actions require confirmation via an in-dashboard modal. If a key is lost (never shown again after mint), regenerate is the recovery path. There is no recovery for a revoked key — you must regenerate.

Bundle version & polling

The script bundle is served at …/TOKEN.js with an ETag derived from account version, test vs production mode, and build identity. Conditional requests can return 304 Not Modified when nothing changed.

The Live Block Updates block (when enabled) polls GET /api/v1/embed/TOKEN/poll?v=…&qrev=… on an interval from your embed’s configured poll interval (dashboard “Live Block Updates” card; test-mode clients may use a faster cadence). That single request carries both the bundle version and any queued remote JavaScript from POST …/embed-console/v1/queue when your plan includes browser_console_api and the embed has the console API enabled.

Turning Live on in production—via dashboard or Gateway API toggles—sets that embed interval to 1 second if it wasn’t already, so edits and remote-queue pushes propagate quickly.

Gateway API

Use an iga_… key from the dashboard (embed key on Embed console & API keys, or account key under Advanced / on /app/embeds) for:

Security. This key can change protection settings, custom blocks, test mode, poll interval, and (when Studio+) enqueue arbitrary JavaScript to run on visitor tabs that load your bundle. Store it in secrets managers / CI only.

  • RESThttps://intigin.com/api/v1/… (blocks, custom blocks, test mode).
  • Embed queuePOST …/api/embed-console/v1/queue with the same Bearer key when browser_console_api is on. Visitors pick up queued scripts via the unified poll (GET …/api/v1/embed/TOKEN/poll). See Embed HTTP API.

If your account has multiple embeds, pass X-Intigin-Embed-Id (hex embed id from GET …/embeds or state) on queue POST and on account-scoped GETs that would otherwise be ambiguous. Embed-scoped URLs /api/v1/embeds/<embed_id>/… always work.

Responses are JSON; successful mutations usually include {"success":true,…}.

Quick start

  1. Credential — Dashboard → Settings → Embed console & API keys → regenerate the Embed API key (or expand Advanced for the account key). Copy the iga_… value once and store it in CI or a secrets manager.
  2. List embedsGET https://intigin.com/api/v1/embeds or GET …/api/v1/account/embeds (same response: ids + script token previews).
  3. State / custom blocks — With one manageable embed: GET …/api/v1/account/state and GET …/api/v1/account/custom-blocks need no embed in the URL. With multiple embeds, send header X-Intigin-Embed-Id or use /api/v1/embeds/<embed_id>/… paths. State includes embed_id and owner_account_id; custom block ids look like ucb_<owner_account_id>_… — they are not embed ids. To see whether a custom block is on in production, check enabled in state (see below), not custom_blocks_ids.
  4. Production vs test — Omit X-Intigin-Scope for production changes. Use X-Intigin-Scope: test + X-Intigin-Test-Code for test storage (see below).

Authentication

One Bearer per scope. Pick the highest scope that already covers what you need (almost always your account or group key — see Chained scoped API keys). Every request (except browser OPTIONS) should include:

Authorization: Bearer <token>

Token types:

  • iga_… Gateway API key — Scope-aware key issued from the dashboard. Each resource can have its own key (embed, account, group, admin). The embed dashboard surfaces the embed key first and the account key under Advanced; the embed list page (/app/embeds) highlights the account key for managing all embeds at once. The hierarchy is implicit: a higher-scope key authorizes everything below it (admin > group > account > embed). See API key scopes below for the full table.

API key scopes

The Gateway API uses scope-aware keys: every embed, every account, and every group each get their own regenerable iga_… key. The same Bearer header is used everywhere; the server resolves the key to a scope + resource id and authorizes each route against that.

Scope Authorizes Where to obtain URL prefix
embed Just one embed (its bundle, custom blocks, queue, poll interval). Dashboard → Settings (embed selected) → Embed API keyRegenerate API key. (Also POST /app/embeds/{eid}/gateway-api/regenerate.) /api/v1/embeds/{eid}/…
account Every embed the account can manage (owned + accessible via group memberships when the actor is owner/group_admin). Dashboard → SettingsAdvanced — Account API keyRegenerate API key. Available on Live tier and up. /api/v1/accounts/{aid}/… (alias: /api/v1/account/… for the actor’s own account).
group Every member account in the group, every embed assigned to the group, and any embed owned by a member account. Dashboard → Groups → expand a group → Regenerate API key. Visible to enterprise owner / group_admin; requires group_management entitlement (Team / Enterprise tier). /api/v1/groups/{gid}/…

Authorization is enforced by a single resolver (intigin_scope_can_act_on(actor, target_type, target_id)): cross-scope attempts return 403 forbidden. Regenerating a key immediately invalidates the previous one — there is no rotation window.

The key’s plaintext is shown once on the dashboard right after you click Regenerate API key; the server only stores password_hash(). Lose it → regenerate again. The same resolver powers the dashboard, so every /app/… mutation goes through the API in-process.

Production vs test scope

Default (production) — Do not send X-Intigin-Scope, or send X-Intigin-Scope: production. Production block toggles, production custom blocks, and production version bumps apply even if test mode is enabled on the account. This avoids CI accidentally writing to test storage.

Test storage — Send X-Intigin-Scope: test and X-Intigin-Test-Code: <same value as ?ig_test=>. Get the code from GET …/state (test_mode_code) or the Test Mode card when test mode is on. If test mode is off, test scope returns 400 with error test_mode_off. Missing or wrong code → 403 (test_code_required / invalid code).

The route …/blocks/{id}/test-toggle always affects test enabled list and always requires test scope + test code (headers above).

GET …/state — which field means “on”?

Production snapshot fields:

  • enabled — Block ids currently active in the visitor bundle for this embed: built-in ids from the blocks-catalog endpoint plus any custom blocks (ucb_…) whose toggle is on. Use block_id in enabled to label a row ON vs OFF.
  • custom_blocks_ids — Every production custom block id that exists in saved storage, whether its toggle is on or off. Membership here does not mean enabled (so comparing list metadata against only this array makes everything look “on”).
  • test_enabled vs test_custom_blocks_ids — Same split for test-side configuration when you use test scope / ?ig_test=.

GET …/account/custom-blocks lists saved blocks (metadata); pairing each row with state["enabled"] gives dashboard-style on/off.

Custom JavaScript teardown. When you turn a custom JS block off (toggle or API) or change its code while Live Block Updates delivers a fresher bundle, the previous run’s timers and DOM nodes created during that run (via standard appendChild paths) are torn down automatically. Tabs without Live Block Updates keep executing the bundle they loaded until they fetch a newer one (typically on full page reload).

Endpoints

Globalhttps://intigin.com/api/v1/blocks-catalog lists built-in protection block ids (for toggles).

Account scope (prefix https://intigin.com/api/v1/account) — Bearer must be an iga_… key (or another actor that resolves to an account for gateway routing). The global site hex key has no tenant account context here and receives 403 forbidden on routes that need one (e.g. GET …/embeds, GET …/account/state). With multiple embeds, send X-Intigin-Embed-Id on any route that targets one embed; the only exceptions are GET …/embeds and GET …/account/embeds (both list all embeds).

For mutations, /api/v1/account/<suffix> mirrors /api/v1/embeds/<embed_id>/<suffix> after resolving the embed (single embed = implicit; multi = header required).

Method Path Purpose
GET /api/v1/blocks-catalog Built-in block ids, labels, sections (protection toggles).
GET /api/v1/embeds Alias of /api/v1/account/embeds — list manageable embed ids (and script token previews).
GET /api/v1/account/embeds Same as GET …/api/v1/embeds.
GET /api/v1/account/state Snapshot: enabled (blocks on in prod), custom_blocks_ids (all saved custom blocks, not toggle state), test_enabled, test_custom_blocks_ids, embed_id, owner_account_id, versions, poll_interval, entitlements; optional X-Intigin-Embed-Id when multiple embeds.
GET /api/v1/account/custom-blocks Custom block metadata (id, label, section, type) for resolved embed; scope headers for test storage.
GET /api/v1/account/custom-blocks/{block_id} Full block including js source; scope headers for test vs production storage.
POST /api/v1/account/poll-interval Body {"poll_interval":30000} (ms). Requires custom poll interval entitlement; same behavior as dashboard.
POST /api/v1/account/embed-console Body {"console_api_enabled":true} or {"enabled":true}. Enables visitor queue delivery on the unified poll for the resolved embed.

Embed scope — prefix https://intigin.com/api/v1/embeds/<embed_id> where embed_id is the lowercase hex id from the list/state (usually 16 characters, not 32). Same suffixes as /account/… mirrors. Additional paths:

Method Path suffix Purpose
GET /state Same payload as GET …/account/state; enabled = on/off for bundle, custom_blocks_ids = all saved custom block keys.
GET /custom-blocks/{block_id} Full custom block record including js; use scope headers for test storage.
POST /poll-interval Same as account route; body {"poll_interval":30000}.
POST /embed-console Same as account route; toggle remote queue for this embed id.
POST /blocks/{block_id}/toggle Body {"enabled":true|false}. Production only; use invalid_scope if you send test scope here.
POST /blocks/{block_id}/test-toggle Same body; test scope + test code required. Bumps test_version.
POST /custom-blocks Create/update. Body: section, label, desc, type (js|css|html), js (code string). Optional: block_id (update), enable_now, default. On updates, if JSON includes "enable_now": false, the block is turned off in the bundle (same as POST …/blocks/…/toggle). Omitting enable_now keeps the prior on/off state.
DELETE /custom-blocks/{block_id} Delete custom block for current scope (production default, or test with scope headers).
POST /test-mode/toggle Body {"enabled":true|false}. Plan must include test mode to turn on.
POST /test-mode/push-to-production Promotes test config to production (tier: push test → production).
POST /test-mode/reset-from-production Reset test state from production snapshot.
POST /test-mode/regenerate-code New ig_test code; invalidates old URLs.

Account, group, and admin namespaces

Beyond per-embed routes, the same Bearer key (matching its scope) reaches account/group/admin namespaces. The matrix below is non-exhaustive — gateway-api/regenerate, status, delete, and read endpoints exist at every level.

Method + path Purpose Required scope
POST /api/v1/embeds/{eid}/gateway-api/regenerateMint a fresh embed-scope key (returns token once).embed/account/group/admin
POST /api/v1/embeds/{eid}/disableDisable the embed (no JS load on visitor pages).account/group/admin
POST /api/v1/embeds/{eid}/deletePermanently delete the embed (and its key).owner-account/group/admin
GET /api/v1/accounts/{aid}Account row + key metadata.account/group/admin
POST /api/v1/accounts/{aid}/passwordChange password (account scope: requires current; admin/group: just sets it).account/group/admin
POST /api/v1/accounts/{aid}/emailUpdate email.account/group/admin
POST /api/v1/accounts/{aid}/statusSet active|iced|suspended|….group/admin
POST /api/v1/accounts/{aid}/tierChange billing tier.admin
POST /api/v1/admin/accounts/{aid}/request-quotaWeekly cap override, grant balance, optional reset of request_used (see Weekly request budget).admin
POST /api/v1/accounts/{aid}/embedsCreate a new embed under this account.account/admin
GET /api/v1/accounts/{aid}/groupsMemberships for the account.account/admin
POST /api/v1/groups/{gid}/gateway-api/regenerateMint a fresh group-scope key.group/admin (account-scope: enterprise owner)
POST /api/v1/groups/{gid}/membersCreate a Tycoon member directly in the group.group/admin
POST /api/v1/groups/{gid}/members/assignAssign existing account into group with a role.group/admin
POST /api/v1/groups/{gid}/members/{aid}/roleSet member role (owner|group_admin|member).group/admin
POST /api/v1/groups/{gid}/embedsCreate + assign a new embed under the group.group/admin
POST /api/v1/groups/{gid}/embeds/assignAssign an existing owner-account embed to the group.group/admin
POST /api/v1/admin/gateway-api/regenerateMint the supreme admin key.admin
POST /api/v1/admin/accountsCreate an account.admin
POST /api/v1/admin/groupsCreate a group (body: name, enterprise_account_id).admin
POST /api/v1/admin/platform/pause-signupsGlobally pause new signups.admin
POST /api/v1/admin/platform/default-tierDefault tier for new signups.admin
POST /api/v1/admin/platform/request-tier-capsJSON body with free, live, studio, tycoon, team integer caps — global weekly request budgets (immediate for all accounts; per-account overrides still apply).admin
POST /api/v1/admin/platform/admin-passwordRotate the global admin password.admin

Calls that target a specific resource use intigin_scope_can_act_on() to authorize: a group key acting on an embed not in the group → 403 forbidden. The dashboard goes through the exact same dispatcher.

Responses and errors

Many endpoints return success, version and/or test_version. On failure, JSON includes "success":false and an error string, for example:

  • unauthorized — missing or invalid Bearer token (401).
  • forbidden — token valid but cannot manage this embed (403).
  • account_locked — account status blocks changes (403).
  • plan_blocked — feature not on tier (403).
  • embed_not_found — bad embed_id (404).
  • test_mode_off, test_code_required — test scope misconfiguration (400/403).
  • invalid_scope — e.g. test scope on production-only route (400).
  • embed_id_required — multiple embeds but no X-Intigin-Embed-Id on account routes or queue (400).
  • custom_block_limit, block_not_found — validation / unknown block.

CORS

Preflight OPTIONS /api/* allows methods including DELETE and headers: Authorization, Content-Type, X-Intigin-Scope, X-Intigin-Test-Code, X-Intigin-Embed-Id. Prefer calling the API from a server or CI (secrets stay off the browser).

Examples (curl)

# Replace TOKEN with an iga_… key (or site API key for operator-only use).

# 1) Read state — single embed (no embed id in URL)
curl -sS -H "Authorization: Bearer TOKEN" \
  "https://intigin.com/api/v1/account/state"

# 1b) Or embed-scoped path (replace EMBED_HEX with embed_id from state — typically 16 hex chars)
curl -sS -H "Authorization: Bearer TOKEN" \
  "https://intigin.com/api/v1/embeds/EMBED_HEX/state"

# 2) Enable a production block (no scope header = production)
curl -sS -X POST -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
  -d '{"enabled":true}' \
  "https://intigin.com/api/v1/embeds/EMBED_HEX/blocks/live_updates/toggle"

# 3) Create/update a production custom block
curl -sS -X POST -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
  -d '{"section":"Custom","label":"Banner","desc":"","type":"js","js":"console.log(\"prod\");","enable_now":true}' \
  "https://intigin.com/api/v1/embeds/EMBED_HEX/custom-blocks"

# 4) Delete production custom block (full ucb_… id from GET custom-blocks or state custom_blocks_ids)
curl -sS -X DELETE -H "Authorization: Bearer TOKEN" \
  "https://intigin.com/api/v1/embeds/EMBED_HEX/custom-blocks/ucb_FULL_BLOCK_ID"

# 5) Test-only save (test mode must be ON; CODE from state or dashboard)
curl -sS -X POST -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" \
  -H "X-Intigin-Scope: test" -H "X-Intigin-Test-Code: CODE" \
  -d '{"section":"Custom","label":"Demo","desc":"","type":"js","js":"console.log(1);"}' \
  "https://intigin.com/api/v1/embeds/EMBED_HEX/custom-blocks"

Examples (JavaScript)

const GATEWAY = "https:\/\/intigin.com";
const TOKEN = process.env.INTIGIN_GATEWAY_KEY; // iga_… from dashboard

async function readState() {
  const r = await fetch(`${GATEWAY}/api/v1/account/state`, {
    headers: { Authorization: `Bearer ${TOKEN}` },
  });
  const data = await r.json();
  if (!data.success) throw new Error(data.error || r.statusText);
  return data;
}

async function toggleBlock(blockId, enabled) {
  const st = await readState();
  const eid = st.embed_id;
  const r = await fetch(
    `${GATEWAY}/api/v1/embeds/${eid}/blocks/${encodeURIComponent(blockId)}/toggle`,
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${TOKEN}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ enabled }),
    }
  );
  return r.json();
}

// Custom block ON/OFF in production: use state.enabled, NOT custom_blocks_ids.
function customBlockIsOn(state, blockId) {
  return Array.isArray(state.enabled) && state.enabled.includes(blockId);
}

HTTP API surface

Under https://intigin.com/api only these prefixes are supported: /api/v1/… (Gateway + automation) and /api/embed-console/… (remote queue / run-local). Everything else returns 404.

Roadmap

Follow-up enhancements may include additional read-only aggregates and stricter rate limits on queue endpoints.

← Back to home