Cylink Developer console v0.1.0

Playground

Send a real request and watch how it was routed, which models ran, and where the time went.

Request

Endpoint
Environment
Headers — set for you
Content-Type: application/json · Authorization: Bearer <session>
⌘ ↵ to send

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.

Requests
—
All time
Completed
—
Share that finished cleanly
Active keys
—
Not revoked or expired
Spend
—
Estimated, all time

Your plan

Current plan —
Sign in to see usage

Recent requests

Sign in to see your requests

Analytics

Request volume and latency for the last seven days.

Requests (7d)
—
Median latency
—
Tokens per request
—

Requests per day

Sign in to see analytics

Usage

Where you stand against your plan's limits this cycle.

Requests this month
—
Left today
—
Cost this month
—
Estimated

Monthly allowance

Sign in to see usage

Resets on the 1st of each month

Today's limit

Sign in to see usage

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.

Current plan —
Sign in to see usage
2 months free

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

ModelBest for
cyanix-quickFastest responses — low-latency or lightweight tasks.
cyanix-vistaBalanced speed and reasoning, large context window.
cyanix-apexComplex, multi-step reasoning, large context window.
cyanix-coreGeneral purpose. Used when model is omitted.

Request body

FieldTypeDescription
messagesarrayRequired. OpenAI-style [{ role, content }] turns, where role is system, user or assistant.
system_promptstringYour 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 / querystringShorthand for a single user turn. Used only when messages is omitted.
modelstringOne of the aliases above. Defaults to cyanix-core.
max_tokensnumberDefaults to 2048, capped at 8192.
streambooleanDefaults 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);
Two things to know. Sampling parameters Cylink doesn't implement — temperature, top_p, n, stop, presence_penalty — are accepted and ignored rather than rejected, so they won't error but won't do anything either. And client.models.list() isn't implemented; use the aliases above.

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

StatusCodeWhat to do
401MISSING_AUTHAdd an Authorization: Bearer header.
401UNAUTHORIZEDThe key is invalid, revoked or expired. Create a new one.
429RATE_LIMITEDYou're over your per-minute or daily limit. Check /usage for what's left.
400BAD_REQUESTMalformed body, or no messages / message / query.
405METHOD_NOT_ALLOWEDUse POST.
502MODEL_ERRORThe upstream model failed. Read the detail field and retry.
500SERVER_MISCONFIGUREDServer-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

Preview

Read-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

EndpointParametersReturns
GET /devit/postslimit 1–50 (default 20), before ISO timestamp for paging, tag, author username.Public posts, newest first.
GET /devit/usersusername required.One public profile.
GET /devit/searchq 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 · OIDC

Let 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

NameURL
Authorizehttps://devit-six.vercel.app/authorize
Tokenhttps://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-token
Userinfohttps://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-userinfo
Issuerhttps://devit-six.vercel.app
Discoveryhttps://nynrocdgmowjgslgfdmc.supabase.co/functions/v1/cx-discovery
JWKShttps://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.

CredentialLifetime
Authorization code2 minutes, single use.
Access token1 hour.
Refresh token30 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

Preview

Connect 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

ToolWhat it does
devit_searchSearch public posts and developer profiles by keyword.
devit_get_postsList recent public posts, optionally by tag or author, paged with before.
devit_get_postRead 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_postsThe collab board: posts looking for a co_founder, beta_tester or contributor (or any).
devit_get_userGet a public profile by username.
devit_whoamiShow 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)

ToolWhat it does
devit_get_notificationsYour notifications and unread count. Filter by types or unread_only. Direct-message notifications are never included.
devit_get_my_postsYour own posts with likes, comments, reposts, views and moderation status.
devit_get_following_feedRecent posts from the people you follow.
devit_get_connectionsYour followers, or the people you follow (kind).
devit_get_collab_requestsCollab requests you received or sent, with their status.
devit_get_link_scansBounceBot'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)

ToolWhat it does
devit_follow_userFollow or unfollow a user by username.
devit_rate_postRate someone else's post 1 to 5, or 0 to clear your rating.
devit_request_collabAsk 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_requestAccept 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)

ToolWhat it does
devit_delete_postPermanently delete one of your own posts, including everyone's comments, likes and ratings on it.
devit_delete_commentPermanently 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)

ToolWhat it does
devit_create_postPublish a public post as you (up to 2000 characters, optional code snippet).
devit_create_commentComment on a post, or reply to a comment (up to 1000 characters).
devit_like_postLike 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.