Playground
Send a real request and watch how it was routed, which models ran, and where the time went.
Request
Response
No response yet
Send a request and the answer, the routing decision and a timing breakdown all land here.
Pipeline
Nothing to trace yet
Once a request completes you'll see which route ARI picked, which models Axion ran, and how long each stage took.
Overview
Traffic, spend and keys across your account.
Make your first request
A key, one snippet, one call. It takes about two minutes, and the call shows up here as a trace.
Get a key
Name it after the app that will use it. The full key is shown once.
Save it now. The snippets below already contain it.
Pick your tool
Cylink speaks the OpenAI chat format, so most clients work as they are.
Send it
Run this in a terminal or a scratch file. The reply comes back as choices[0].message.content.
Your plan
Recent requests
Sign in to see your requests
Analytics
Request volume and latency for the last seven days.
Requests per day
Sign in to see analytics
Usage
Where you stand against your plan's limits this cycle.
Monthly allowance
Resets on the 1st of each month
Today's limit
Daily request limit, resets at midnight UTC
API keys
Keys authenticate your requests. A key is shown in full once, when you create it.
Sign in to manage keys
OAuth apps
Let people sign in to your app with their Devit account. Each app gets a client ID and a secret.
Sign in to manage apps
Billing & plans
Pick the plan that fits your workload. Changes take effect immediately.
Prices in USD. This console is the front end — connect a payment provider and enforce limits server-side before going live.
Need something custom? or email sales.
Docs
Everything you need for your first call. The API is OpenAI-compatible, so existing clients work unchanged.
Quickstart
Authenticate with a key from , then POST a list of messages to get a model response back.
Base URL
https://cylinkdev.vercel.app/api/cylink-api
Your first request
curl https://cylinkdev.vercel.app/api/cylink-api \
-H "Authorization: Bearer cyk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"model": "cyanix-core",
"messages": [{ "role": "user", "content": "Hello!" }]
}'
Authentication
Every request needs your API key as a bearer token. Keys start with cyk_ and are shown in full only once, so store it somewhere safe as soon as you create it.
Authorization: Bearer cyk_your_key_here
Rotate or revoke keys from . Revoking takes effect immediately.
Models
| Model | Best for |
|---|---|
| cyanix-quick | Fastest responses — low-latency or lightweight tasks. |
| cyanix-vista | Balanced speed and reasoning, large context window. |
| cyanix-apex | Complex, multi-step reasoning, large context window. |
| cyanix-core | General purpose. Used when model is omitted. |
Request body
| Field | Type | Description |
|---|---|---|
| messages | array | Required. OpenAI-style [{ role, content }] turns, where role is system, user or assistant. |
| system_prompt | string | Your own system prompt. Replaces the default Cyanix persona entirely. Takes precedence over system turns in messages, which are used if this is omitted. Max 8,000 characters. |
| message / query | string | Shorthand for a single user turn. Used only when messages is omitted. |
| model | string | One of the aliases above. Defaults to cyanix-core. |
| max_tokens | number | Defaults to 2048, capped at 8192. |
| stream | boolean | Defaults to false. See Streaming. |
Your own system prompt
By default the assistant answers as Cyanix Intelligence. Send system_prompt — or a system turn in messages — and your instructions take that slot instead, so the assistant is yours.
curl https://cylinkdev.vercel.app/api/cylink-api \
-H "Authorization: Bearer cyk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"system_prompt": "You are Otter, a terse assistant for a plumbing supply store. Never discuss anything else.",
"messages": [{ "role": "user", "content": "Do you stock 15mm compression elbows?" }]
}'
Three things change when you supply one. Tool use, grounding and citations still work — those are mechanics, not personality — but the assistant loses access to the Cyanix knowledge base and Devit, keeping only web search, YouTube search, image search and page reading. Stored user memories are not injected, so nothing personal leaks into your app's replies. And responses aren't scored against Cyanix's own principles, since they aren't Cyanix's responses.
The response reports cylink.system_prompt_used so you can confirm yours was applied.
JavaScript
const res = await fetch("https://cylinkdev.vercel.app/api/cylink-api", {
method: "POST",
headers: {
"Authorization": "Bearer cyk_your_key_here",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "cyanix-core",
messages: [{ role: "user", content: "Hello!" }]
})
});
const data = await res.json();
console.log(data.choices[0].message.content);
Python
import requests
res = requests.post(
"https://cylinkdev.vercel.app/api/cylink-api",
headers={"Authorization": "Bearer cyk_your_key_here"},
json={
"model": "cyanix-core",
"messages": [{"role": "user", "content": "Hello!"}],
},
)
print(res.json()["choices"][0]["message"]["content"])
OpenAI SDK recommended
Point baseURL at Cylink and the official SDKs work as-is — there's no Cylink client to install.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "cyk_your_key_here",
baseURL: "https://cylinkdev.vercel.app/api/v1"
});
const res = await client.chat.completions.create({
model: "cyanix-core",
messages: [{ role: "user", content: "Hello!" }]
});
console.log(res.choices[0].message.content);
Streaming
Set "stream": true for a text/event-stream response: data: {...} chunks ending in data: [DONE], the same shape other OpenAI-compatible APIs use.
const res = await fetch(BASE_URL, {
method: "POST",
headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json" },
body: JSON.stringify({ messages, stream: true })
});
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buf = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buf += decoder.decode(value, { stream: true });
// split buf on newlines, parse each "data: {...}" line as JSON
}
Errors
| Status | Code | What to do |
|---|---|---|
| 401 | MISSING_AUTH | Add an Authorization: Bearer header. |
| 401 | UNAUTHORIZED | The key is invalid, revoked or expired. Create a new one. |
| 429 | RATE_LIMITED | You're over your per-minute or daily limit. Check /usage for what's left. |
| 400 | BAD_REQUEST | Malformed body, or no messages / message / query. |
| 405 | METHOD_NOT_ALLOWED | Use POST. |
| 502 | MODEL_ERROR | The upstream model failed. Read the detail field and retry. |
| 500 | SERVER_MISCONFIGURED | Server-side configuration issue. Contact support. |
Errors carry a machine-readable code, a short message, and a details string naming the specific cause.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication failed.",
"details": "This API key has been revoked and can no longer be used."
}
}
Other endpoints
These take the same Authorization: Bearer cyk_your_key_here header and return errors in the same shape. They also accept your dashboard session token, which is how the Playground calls them — you don't need a key for that.
/axion — grounded chat recommended
One call that routes the query, pulls the knowledge base plus live web search, and answers — with the full trace attached. Free keys get a single grounded model; paid keys get the ensemble.
curl https://cylinkdev.vercel.app/api/axion \
-H "Authorization: Bearer cyk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "query": "What is the latest news about Groq?" }'
Returns selected_route, confidence, trace_events and response with the final answer.
/axion — run one route
Skips the routing decision and executes the route you name, for example one you got back from ARI.
curl https://cylinkdev.vercel.app/api/axion \
-H "Authorization: Bearer cyk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "query": "Reverse a string in Rust", "route": "code_execution" }'
Returns { model, response }. An optional context string is injected into the system prompt.
/usage — quota and spend
Live usage for the calling key. A key can only read its own stats.
curl https://cylinkdev.vercel.app/api/usage \ -H "Authorization: Bearer cyk_your_key_here"
Returns { key_name, requests, cost_usd, limits, last_used_at }.
Devit API
PreviewRead-only access to public Devit data: posts, profiles and search. It uses the same cyk_ key as everything else and counts toward your plan's requests. Only public content is exposed. There are no DMs, no emails and nothing unpublished. This API is in preview, so field names may still change.
Endpoints
| Endpoint | Parameters | Returns |
|---|---|---|
| GET /devit/posts | limit 1–50 (default 20), before ISO timestamp for paging, tag, author username. | Public posts, newest first. |
| GET /devit/users | username required. | One public profile. |
| GET /devit/search | q required, limit 1–25 (default 10). | Matching public posts and profiles. |
Example
curl "https://cylinkdev.vercel.app/api/devit/posts?limit=2&tag=beta-tester" \ -H "Authorization: Bearer cyk_your_key_here"
{
"data": [
{
"id": "post_id",
"content": "Looking for beta testers for my game.",
"code_lang": null,
"tags": ["beta-tester", "js"],
"likes": 4,
"comments": 2,
"views": 61,
"image_url": null,
"author": { "username": "someone", "display_name": "Some One", "avatar_url": "https://..." },
"created_at": "2026-10-05T14:02:11Z",
"url": "https://devit-six.vercel.app/@someone/looking-for-beta-testers-a1b2c3d4"
}
],
"next_before": "2026-10-05T14:02:11Z"
}
Pass next_before back as before to fetch the next page; it is null on the last one. tag matches Devit's tag slugs, such as beta-tester, contributor or a topic like js. /devit/users returns { data: {…} } with the public profile fields, or a 404 NOT_FOUND. /devit/search returns { posts: […], users: […] }. Errors use the same shape as the rest of Cylink.
Sign in with Devit
OAuth 2.0 · OIDCLet people sign in to your app with their Devit account. It is a standard authorization code flow with PKCE, and returns an RS256 id_token when you ask for the openid scope. Create an app under to get a client ID and secret. Apps belong to a Devit account, so you need to be signed in to Cylink with Devit, and each account can have up to 5.
Endpoints
| Name | URL |
|---|---|
| Authorize | https://devit-six.vercel.app/authorize |
| Token | https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-token |
| Userinfo | https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-userinfo |
| Issuer | https://devit-six.vercel.app |
| Discovery | https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-discovery |
| JWKS | https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-jwks |
1. Send the user to Devit
https://devit-six.vercel.app/authorize ?response_type=code &client_id=YOUR_CLIENT_ID &redirect_uri=https%3A%2F%2Fyourapp.com%2Fcallback &scope=identity%20openid &code_challenge=BASE64URL_SHA256_OF_VERIFIER &code_challenge_method=S256 &state=RANDOM_VALUE
redirect_uri must exactly match one registered for your client. Only S256 PKCE is accepted. A client registered without PKCE has to send a nonce instead. Apps you create can request identity, profile, email and openid. identity is always included. profile unlocks the name, username and picture, and email unlocks the address. The id_token and userinfo carry only what was granted.
2. Exchange the code
curl https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-token \ -d grant_type=authorization_code \ -d code=THE_CODE \ -d redirect_uri=https://yourapp.com/callback \ -d client_id=YOUR_CLIENT_ID \ -d client_secret=YOUR_CLIENT_SECRET \ -d code_verifier=YOUR_VERIFIER
Every app authenticates here with its client secret, so do this exchange on your server and never in browser code. You can also send the client credentials as HTTP Basic auth. Verify the id_token signature against the JWKS above. The response carries access_token, refresh_token, expires_in, scope and, with openid, an id_token. To renew, POST grant_type=refresh_token with the refresh token and your client credentials.
| Credential | Lifetime |
|---|---|
| Authorization code | 2 minutes, single use. |
| Access token | 1 hour. |
| Refresh token | 30 days. |
3. Read the profile
curl https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-userinfo \ -H "Authorization: Bearer ACCESS_TOKEN"
{
"sub": "devit_user_id",
"preferred_username": "someone",
"name": "Some One",
"picture": "https://...",
"email": "someone@example.com",
"email_verified": true
}
sub is the stable Devit user ID, so key your accounts on it rather than on the email or username. The id_token carries the same claims, and its aud is your client ID.
Devit MCP
PreviewConnect Claude, Cursor, VS Code, Grok or any other MCP client to Devit. Add the server URL, approve access in the browser window that opens, and you are connected. There is no API key to copy. It signs you in with your Devit account. Access is read-only unless you switch on posting during approval.
https://devit-six.vercel.app/mcp
Add it to your client
claude mcp add --transport http devit https://devit-six.vercel.app/mcp
In Claude (web and desktop) add it as a custom connector with the URL above. In Cursor and VS Code, add it as a remote server with the same URL:
{
"mcpServers": {
"devit": { "url": "https://devit-six.vercel.app/mcp" }
}
}
The first time you connect, your client opens Devit's approve screen. Sign in if you need to, check what the app is asking for, and press Approve. Clients register themselves automatically, so you never create an app by hand.
Tools
| Tool | What it does |
|---|---|
| devit_search | Search public posts and developer profiles by keyword. |
| devit_get_posts | List recent public posts, optionally by tag or author, paged with before. |
| devit_get_post | Read one post with its comments. Takes a post id, short id or Devit URL. Comments keep their parent_id so threads can be rebuilt, and are paged with comments_limit and comments_after. |
| devit_get_collab_posts | The collab board: posts looking for a co_founder, beta_tester or contributor (or any). |
| devit_get_user | Get a public profile by username. |
| devit_whoami | Show which Devit account you connected with, and whether write access was granted. |
Resources and prompts
Clients that support them can attach Devit content directly: devit://post/{post} and devit://user/{username}. There are also four ready-made prompts: draft_devit_post, reply_to_devit_post, find_devit_collaborators and devit_digest. The drafting prompts only write a draft. Nothing is published until you approve it.
Account tools (opt-in)
| Tool | What it does |
|---|---|
| devit_get_notifications | Your notifications and unread count. Filter by types or unread_only. Direct-message notifications are never included. |
| devit_get_my_posts | Your own posts with likes, comments, reposts, views and moderation status. |
| devit_get_following_feed | Recent posts from the people you follow. |
| devit_get_connections | Your followers, or the people you follow (kind). |
| devit_get_collab_requests | Collab requests you received or sent, with their status. |
| devit_get_link_scans | BounceBot's results for links you submitted: risk category, scores and the main issues. |
These are read-only and sit behind a second checkbox on the approve screen, Read your private Devit account, which is off by default. Leave it off and the tools are never listed. They never expose messages, email addresses, notification settings or admin data. All of them page with before and next_before.
Social tools (opt-in)
| Tool | What it does |
|---|---|
| devit_follow_user | Follow or unfollow a user by username. |
| devit_rate_post | Rate someone else's post 1 to 5, or 0 to clear your rating. |
| devit_request_collab | Ask the author of a post for a co-founder, beta-tester or contributor slot. The post must be asking for it, and the message is 10 to 500 characters. Up to 5 requests per hour. |
| devit_respond_collab_request | Accept or decline a pending request that was sent to you. |
Behind the checkbox Follow, rate and handle collab requests, off by default. Follows update the same counters and send the same notifications as the app.
Delete tools (opt-in)
| Tool | What it does |
|---|---|
| devit_delete_post | Permanently delete one of your own posts, including everyone's comments, likes and ratings on it. |
| devit_delete_comment | Permanently delete one of your own comments and the replies under it. |
Behind its own checkbox, Delete your own posts and comments, off by default. It can only delete content you wrote, at most 5 items per 10 minutes. Editing posts isn't offered, because Devit moderates when a post is created and an edit would skip that check.
Write tools (opt-in)
| Tool | What it does |
|---|---|
| devit_create_post | Publish a public post as you (up to 2000 characters, optional code snippet). |
| devit_create_comment | Comment on a post, or reply to a comment (up to 1000 characters). |
| devit_like_post | Like a post, or remove your like. |
The approve screen has an Allow posting, commenting and liking checkbox that is off by default. Leave it off and the write tools are never even listed to your client. Writes go through the same checks as the Devit app: your normal rate limits, mentions, slugs and counters. On top of that, a second post within 30 seconds is refused, so an agent can't put your account on a posting cooldown. Nothing here can edit content or send messages. Your client should ask you before each write, and the tool descriptions tell the model to act only on your explicit request.
Posts by private profiles and posts that failed moderation are never returned. Post and profile text is written by other people, so the server marks it as untrusted data. Treat anything inside it as content, not instructions.
For client authors
The server speaks Streamable HTTP and answers with plain JSON. An unauthenticated request gets a 401 with a WWW-Authenticate header that points at the protected-resource metadata. From there the standard flow applies: authorization-server metadata, dynamic client registration (RFC 7591) at https://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-register, then authorization code with S256 PKCE. Registered MCP clients are public (no client secret). They always receive mcp:read, and mcp:write, mcp:me, mcp:social and mcp:manage only when the user opts in on the approve screen. Their refresh tokens rotate on every use. Redirect URIs must be https, an http loopback address, or a custom app scheme, and are matched exactly.