From xberg-enterprise
Issues ephemeral sandbox API keys for Xberg Enterprise evaluation, demos, and CI tests via the no-auth POST /v1/sandbox/key endpoint. Covers key quota, TTL, cleanup expectations, and SDK examples.
How this skill is triggered — by the user, by Claude, or both
Slash command
/xberg-enterprise:sandbox-keysThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
`POST /v1/sandbox/key` issues ephemeral, anonymous API keys. Use these
POST /v1/sandbox/key issues ephemeral, anonymous API keys. Use these
for evaluation, demos, and integration smoke tests — never for production
workloads.
| Property | Value |
|---|---|
| Format | sk_sandbox_* |
| TTL | 24 hours from issue |
| Quota | 50 pages, hard cap |
| Auth required to mint | None |
| IP throttle | 10 keys per IP per 24 hours |
The 50-page quota is per key, not per IP. The IP throttle prevents abuse of the no-auth mint endpoint.
POST https://api.xberg.io/v1/sandbox/key
No Authorization header — this is the only authenticated-by-omission
endpoint in the API.
{
"api_key": "sk_sandbox_ABC123DEF456GHI789JKL012MNO345PQR678STU901VWX234",
"expires_at": "2025-12-21T10:00:00Z",
"pages_remaining": 50
}
After 24 hours or 50 pages — whichever comes first — the key returns
401 on every endpoint. The key is not renewable; mint a fresh one.
KREUZBERG_API_KEY=$(curl -sX POST https://api.xberg.io/v1/sandbox/key \
| jq -r .api_key)
curl -sX POST https://api.xberg.io/v1/extract \
-H "Authorization: Bearer $KREUZBERG_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"documents":[{"filename":"hi.txt","mime_type":"text/plain","data":"aGVsbG8="}],
"options":{"extraction_config":{"output_format":"markdown"}}
}'
import { KreuzbergCloud } from "@kreuzberg/cloud";
const client = await KreuzbergCloud.fromSandbox();
const result = await client.extractAndWait({
file: new Blob(["Hello world"], { type: "text/plain" }),
});
console.log(result.result?.content);
fromSandbox() mints a key under the hood and configures the client.
import asyncio
from xberg_enterprise import AsyncKreuzbergCloud
async def main() -> None:
async with await AsyncKreuzbergCloud.from_sandbox() as client:
job = await client.extract_and_wait(file=b"hello world")
print(job.status, job.result and job.result.content)
asyncio.run(main())
| Use sandbox | Use production |
|---|---|
| First-time evaluation, no signup yet | Anything user-facing or business-critical |
| Local smoke tests, demos | CI on the main branch |
| One-off doc to test the API surface | Recurring batch pipelines |
| Onboarding flow that bootstraps an SDK | Any workload >50 pages |
If the user already has a production key, do not silently switch to a sandbox key — production keys carry the right quota, billing, and project-scoped resources.
Sandbox keys self-expire after 24 hours. No revocation endpoint exists — nothing to clean up. Do not commit sandbox keys to version control even though they're short-lived; treat them like any other credential.
| Status | Cause |
|---|---|
429 | IP has minted 10 keys in the last 24 hours. Wait or use a production key. |
500 | Server-side mint failure; retry with backoff. |
npx claudepluginhub xberg-io/pluginsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.