Guide · 02

Make a block externally accessible

You shipped a block. Now make it reachable from a website, a script, an iframe, or another service. Five patterns, all using primitives that already exist on the platform — no new servers, no extra hosting.

The big picture

Every block has the same canonical URL once it's published:

https://blocks.gonka.gg/blocks/<author>/<slug>

From there, the platform exposes five distinct surfaces — depending on how you want callers to interact with it. Pick whichever fits the integration; you can use multiple at once.

SurfaceBest forAuth
Block pageDirect human use, "here's a tool" linksPublic · anon · signed-in
Embed iframeDrop into your own website, blog, docPublic · anon · signed-in
CLIScripts, CI, terminal useAPI key (one-time login)
Service blockAlways-on HTTP API, OpenAI-compatiblePublic route or scoped key
REST APITrigger runs from your own backendAPI key

1. Make the block public

Every other surface assumes this is on. From the block's page (/blocks/<you>/<slug>), open the settings panel and toggle Public. Until you do this, only you can see and run the block.

Public means:

  • The block appears in the public Library. Visitors can fork it.
  • Anyone with the URL can run it — including anonymous visitors, subject to the per-IP free-tier quota (10 runs / week, fixed 50¢ per-run cap).
  • Signed-in callers run it against their own credit balance and their own per-run cap.

Public does not mean your code is open. The Docker image is opaque — only the manifest, description, and inputs/ outputs are visible. Fork-able means "runnable as your own", not "source-available". (If you want to share source, push it to GitHub and link from the description.)

2. The public block page

For a lot of integrations, the block page is the only thing you need. It's a self-contained run-form with auto-built input controls, a live log streamer, an inference timeline, and a downloadable output card.

https://blocks.gonka.gg/blocks/<author>/<slug>

You can also pre-fill the form via query parameters whose names match your manifest input keys:

https://blocks.gonka.gg/blocks/admin/hive-research?topic=Gonka+network&depth=2

Use this for "Try it" buttons in your own docs — link directly with the inputs filled in, the visitor only has to click Run.

3. Embed as an iframe

Every public block has a stripped-down embeddable URL with no global navigation chrome. Drop it into any HTML page in four lines:

<iframe
  src="https://blocks.gonka.gg/embed/admin/hive-research?h=420"
  width="100%" height="420" frameborder="0"></iframe>

What the visitor sees:

  • The block title, author, and a one-line description.
  • An auto-generated form for every declared input.
  • A "Run" button that calls POST /api/runs with their inputs.
  • A streaming log panel and the final output, all inline.
  • An "Open ↗" link that opens the full block page in a new tab — useful when they want to bookmark, fork, or share.

Pre-fill works the same way as on the block page:

<iframe
  src="https://blocks.gonka.gg/embed/admin/read-url?url=https%3A%2F%2Fexample.com"
  width="100%" height="380" frameborder="0"></iframe>

Caveats:

  • Anonymous quota applies to the visitor's IP, not your site. Heavy traffic on a public embed will quota-out anonymous users at 10 runs/week.
  • To remove the quota, your visitors need accounts. The embed shows a Sign in link in that case.
  • The iframe loads with SAMEORIGIN framing headers; if you embed on a third-party domain, that's allowed by design — check your CSP if you have one.

4. Run from the CLI

For scripts, CI, terminal pipelines. The CLI authenticates once and then talks to the platform via your long-lived API key.

# one-time setup (one-line installer)
curl -fsSL https://blocks.gonka.gg/install.sh | sh
# or: npm install -g @gonkalabs/blocks-cli
gonkablocks connect --server https://blocks.gonka.gg

# trigger a run, key=value style for inputs
gonkablocks run admin/hive-research \
  topic="quantum networking" depth=3

# output:
#   starting run…
#   ✓ run started: https://blocks.gonka.gg/runs/<id>
#    • running
#    • succeeded
#   outputs: {
#     "report_path": "report.md",
#     "sub_questions": ["...", "..."]
#   }

The CLI tails the run, prints status transitions, and dumps outputs.json on success. Wrap it in shell scripts, cron, GitHub Actions — same shape as any other CLI tool.

Other useful sub-commands:

  • gonkablocks runs — list recent runs across all your blocks.
  • gonkablocks exec -- <cmd> — wrap any local subprocess as an observed cloud Run, with metering and the inference proxy already wired.
  • gonkablocks env — print shell exports so any local code can talk to the inference proxy directly.

5. Deploy as a Service (HTTP)

Some blocks are inherently always-on: an OpenAI-compatible chat endpoint, an MCP server, a Slack-ingest webhook receiver. For those, set type: service in the manifest, expose a port, and the platform fronts you with a public URL.

# manifest.yaml
name: aurora-chat
version: 0.1.0
type: service
description: OpenAI-compatible chat backed by Qwen3, with a custom system prompt.

runtime:
  build: dockerfile
  entrypoint: python server.py
  expose_port: 8080
  env:
    MODEL: qwen3-235b

resources:
  cpu: 1
  memory_mb: 1024
  network: deny

Inside the container, listen on 0.0.0.0:<expose_port>. After deploy + start, the platform routes any request matching the canonical URL to your container:

# any path, any method, with body — proxied to your container
curl https://blocks.gonka.gg/services/<author>/aurora-chat/v1/chat/completions \
  -H "Authorization: Bearer gk-live-..." \
  -H "content-type: application/json" \
  -d '{
    "model": "qwen3-235b",
    "messages": [{"role": "user", "content": "Hi!"}]
  }'

What the platform handles for you:

  • TLS, edge routing, and per-service public DNS — no nginx, no Caddy.
  • Auth in front. If the service is marked public, anyone can hit it. If private, only the owner's scoped keys (or session) get through.
  • Logs, metrics, per-call inference traces — same as for jobs and sessions.
  • The same OPENAI_BASE_URL/OPENAI_API_KEY env vars are injected so your service can call models on Gonka with zero config.

Start, stop, and view a service from /services/<author>/<slug> on the dashboard. Service blocks have a manual Deploy step (start a container) separate from publishing a new version, so you can test the manifest without traffic.

6. REST API + scoped keys

Two REST endpoints worth knowing about, served at the platform origin (default https://blocks.gonka.gg):

Trigger a run

POST /api/runs
Authorization: Bearer gk-live-...           # your account's API key
content-type: application/json

{
  "blockId": "<the cuid of the block>",
  "inputs":  { "topic": "...", "depth": 3 },
  "spendCapCents": 100                      # optional
}

→ 200 { "runId": "cmoxxx..." }

How to get a blockId:

GET /api/blocks/resolve?author=<author>&slug=<slug>
Authorization: Bearer gk-live-...

→ 200 { "blockId": "cmo..." }

Once the run is started, stream events from the same WebSocket the run viewer uses:

# subscribe to the run's event stream
wscat -c "wss://blocks.gonka.gg/ws/runs/<runId>"

# events:
#   { "type": "status",         "payload": { "status": "running"   } }
#   { "type": "stdout",         "payload": "==> Step 1: ..."        }
#   { "type": "inference_call", "payload": { "model": "...", ... } }
#   { "type": "output",         "payload": { ...your outputs... }  }
#   { "type": "status",         "payload": { "status": "succeeded" } }

Or poll GET /api/runs/<runId> if WebSockets aren't convenient.

Inference passthrough

If you just want cheap models in your own app — no block at all — the inference proxy exposes the OpenAI / Anthropic protocol directly. Same key works:

# OpenAI client
from openai import OpenAI
client = OpenAI(
    base_url="https://blocks.gonka.gg/v1",
    api_key="gk-live-...",         # your platform key
)
resp = client.chat.completions.create(
    model="qwen3-235b",
    messages=[{"role": "user", "content": "Hi!"}],
)

Your gk-live-... key is auto- bound to a rolling "adhoc" run that the platform opens behind the scenes — every call shows up in your dashboard with full request/response, cost, and timing. No server-side glue required.

Issuing keys

Manage long-lived API keys at /settings. The raw key is shown once at creation; we store only the hash + a prefix. If you lose a key, revoke it and mint a new one.

7. Share single runs by link

Sometimes you want to send someone the result rather than the tool. Every run has a share button that generates a public read-only link:

https://blocks.gonka.gg/r/<token>

The token is a one-way capability — anyone with the link can view the run (logs, outputs, files, downloadable artefacts) but can't re-run, fork, or read your other runs. Revoke from the run page when you're done.

Anonymous runs (visitors who hit a public block without an account) get an implicit share token: the run id itself acts as a bearer for the user who started it, so they can come back to their results later from the same browser.

Auth at a glance

You are…How you authenticateWhere it works
An anonymous visitornothing — IP-rate-limitedblock page, embed, public services
A signed-in browser usersession cookieeverywhere on the dashboard
A CLI / scriptAuthorization: Bearer gk-live-.../api/*, the inference proxy, services
A block's container at run timeauto-injected OPENAI_API_KEY=sk-run-...scoped to that one Run only

Quotas, billing, and limits

  • Free for everyone right now — Gonka Labs is sponsoring all runs and inference while the platform is young. Every "Free" pill in the UI carries a tooltip explaining this. We'll announce well in advance if/when this changes.
  • Anonymous quota — generous (1000 runs / IP + cookie / week), hard 50¢ spend cap per run as a runaway guard, no session/service access.
  • Signed-in quota — effectively unlimited. Per-run spend cap is still a slider (default 50¢, max $1000) to keep accidental loops from doing damage.
  • Block-level pricing — the manifest's pricing.inference_pass_through field still governs what happens when sponsorship ends. Until then everything is free regardless.
  • Per-run scoped keys — every block run gets a fresh sk-run-... bound to a spend cap. The key dies when the run ends. There's no long-lived secret in the container.

Production checklist

When you're ready to put a block in front of real users:

  1. Toggle Public on the block page. (Confirm inputs / description read well to a stranger.)
  2. Set a sensible default spend cap in the manifest. Anonymous users are pinned to 50¢; signed-in users fall back to the slider default.
  3. Pre-fill examples in your docs by query string, so visitors can hit Run on the first click.
  4. Decide the surface: full page link in your README; iframe embed in a marketing page; service for an API integration; CLI for scripted usage.
  5. Mint a dedicated API key for every backend integration so you can revoke a single one without rotating everything.
  6. Watch the run viewer for the first few real calls — every inference is recorded with prompt, response, cost, and timing. You'll spot prompt regressions immediately.

That's the whole external-access toolbox. Anything you can host on a regular cloud, you can host on Gonkablocks — with free inference baked in and no API-key plumbing to write.