Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Quickstart

In ten minutes you'll go from a .scaicore-ir bundle on disk to a running Core in your tenant with a resolvable checkpoint. The bundle itself is produced by ScaiCore's compiler — see /docs/scaicore for how to author and build one. This page is about hosting that bundle inside ScaiGrid.

You need:

  • A ScaiGrid API key with scaicore:manage (any tenant admin has this).
  • A .scaicore-ir bundle, or a JSON IR dict you've already produced.
bash
1
2
export SCAIGRID_HOST="https://scaigrid.scailabs.ai"
export SCAIGRID_API_KEY="sgk_..."

1. Parse the bundle#

The /parse-bundle endpoint accepts either the binary .scaicore-ir format (starts with the SCIR magic) or a JSON dump of the same dict. It returns the parsed IR plus a summary you can show in the UI.

bash
1
2
3
curl -X POST "$SCAIGRID_HOST/v1/modules/scaicore/cores/parse-bundle" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -F "file=@my-agent.scaicore-ir"
python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import httpx, os

with open("my-agent.scaicore-ir", "rb") as f:
    r = httpx.post(
        f"{os.environ['SCAIGRID_HOST']}/v1/modules/scaicore/cores/parse-bundle",
        headers={"Authorization": f"Bearer {os.environ['SCAIGRID_API_KEY']}"},
        files={"file": ("my-agent.scaicore-ir", f)},
    )
parsed = r.json()["data"]
print(parsed["summary"])
javascript
1
2
3
4
5
6
7
8
9
const form = new FormData();
form.append("file", await Bun.file("my-agent.scaicore-ir").stream(), "my-agent.scaicore-ir");
const res = await fetch(`${process.env.SCAIGRID_HOST}/v1/modules/scaicore/cores/parse-bundle`, {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.SCAIGRID_API_KEY}` },
  body: form,
});
const { data: parsed } = await res.json();
console.log(parsed.summary);

The summary block tells you the IR's name, version, schema version, flow names, model names, identity persona, whether the bundle declares triggers or plugins, and an avatar (base64) if one was embedded. Bundles are capped at 10 MB.

2. Create the Core#

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
curl -X POST "$SCAIGRID_HOST/v1/modules/scaicore/cores" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Quickstart Agent",
    "runtime_mode": "event_driven",
    "concurrency_mode": "stateless",
    "source": '"$(jq -c .source < parsed.json)"',
    "checkpoint_mode": "auto",
    "privilege_level": "standard"
  }'
python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
core = httpx.post(
    f"{os.environ['SCAIGRID_HOST']}/v1/modules/scaicore/cores",
    headers={"Authorization": f"Bearer {os.environ['SCAIGRID_API_KEY']}"},
    json={
        "name": "Quickstart Agent",
        "runtime_mode": "event_driven",
        "concurrency_mode": "stateless",
        "source": parsed["source"],
        "checkpoint_mode": "auto",
        "privilege_level": "standard",
    },
).json()["data"]
print(core["id"], core["slug"], core["status"])
javascript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
const res = await fetch(`${process.env.SCAIGRID_HOST}/v1/modules/scaicore/cores`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCAIGRID_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Quickstart Agent",
    runtime_mode: "event_driven",
    concurrency_mode: "stateless",
    source: parsed.source,
    checkpoint_mode: "auto",
    privilege_level: "standard",
  }),
});
const { data: core } = await res.json();
console.log(core.id, core.slug, core.status);

The slug is auto-generated from the name and must be unique within the tenant. Status starts at created.

3. Start it#

bash
1
2
curl -X POST "$SCAIGRID_HOST/v1/modules/scaicore/cores/$CORE_ID/start" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY"

Start validates the security context for the Core's privilege level, decrypts and resolves any environment variables, resolves identity (service-account by default), composes the system prompt with any bound skills, and transitions through starting to running. If validation fails the Core moves to error.

4. Resolve a checkpoint#

If the Core's execution hits a checkpoint block, ScaiGrid creates a row in mod_scaicore_checkpoints, resolves the assignee, and (if a notifier is configured) emails them. List your own pending checkpoints:

bash
1
2
curl "$SCAIGRID_HOST/v1/modules/scaicore/checkpoints" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY"

Resolve one:

bash
1
2
3
4
curl -X POST "$SCAIGRID_HOST/v1/modules/scaicore/checkpoints/$CP_ID/resolve" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "decision": "approve", "comment": "Looks good." }'

The Core's execution resumes from where it suspended. See Checkpoints for the full lifecycle and Approval flow for the wiring.

What just happened#

  • The bundle's IR was parsed into a source dict and stored against your tenant.
  • Starting the Core ran security validation, environment-variable resolution (decrypting any secrets), identity resolution, and skill-preamble composition before transitioning to running.
  • Checkpoints created by the running Core are persisted in MariaDB and routed by assignee (user, group, role, or delegated user).
  • Resolving the checkpoint writes the decision back to the checkpoint row; ScaiGrid's runtime picks it up and resumes the suspended execution.

Next#

  • Architecture — the wrapper's responsibilities vs. the language runtime.
  • Approval flow — full HITL walkthrough including ScaiQueue integration.
  • Publish as model — expose the Core through /v1/inference/chat.
Updated 2026-05-18 15:01:29 View source (.md) rev 11