curl -X POST "$CODIA_ORIGIN/v1/code/render" \
-H "Authorization: Bearer $CODIA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "const message = \\\"Hello, Codia\\\";\\nconsole.log(message);",
"language": "typescript",
"format": "png",
"theme": "github-dark",
"filename": "app.ts",
"quality": 2
}'Add code image generation to your workflow.
Sign in, create a credential, and send one simple HTTP request to generate code images for docs, sharing, and automated workflows.
Quick start
Request headers
| Parameter | Type | Description |
|---|---|---|
Authorization | Bearer | Required. Use the credential created after signing in. |
Content-Type | application/json | Required when sending the JSON request body. |
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | Yes | The source code to render. 1-50,000 characters. |
language | string | No | Shiki language id, such as typescript or python. If omitted, Codia detects it automatically. |
format | "webp" | "png" | "jpg" | "jpeg" | No | Output image format. All account levels may use any supported format; jpg is normalized to jpeg. |
theme | string | No | Shiki theme name. All account levels may use any bundled theme. |
style | enum | No | Image layout style. Defaults to default; vercel uses a black thin-frame layout with theme highlighting only, hides line numbers, avatars, and the language icon, and keeps dark crosses only at the top-left and bottom-right. Its dynamic minimum width is strictly greater than 440px. |
innerPadding | integer | No | Distance from vercel code to the surrounding frame lines in px. Defaults to 16; range 0-120. Ignored by default style. |
filename | string | No | Optional filename/title shown between the mock window controls and language icon. |
bgColor | string | No | Outer image background. All account levels may use colors and linear/radial gradients. |
backgroundColor | string | No | Legacy alias for bgColor. Prefer bgColor for new integrations. |
borderSize | integer | No | Outer padding in px. Defaults to 12; range 0-120. |
borderRadius | integer | No | Code window radius in px. Defaults to 4; range 0-119. |
containerWidth | integer | No | Requested code container width in px. Defaults to 600; must be positive and is capped at 1920. Values below the dynamic minContainerWidth are raised to that minimum. |
minLines | integer | No | Minimum rendered code line count. Defaults to 3; range 1-1000. Blank lines are appended when needed. |
endSpaceLines | integer | No | Number of blank lines appended after the code. Defaults to 2; range 0-1000. Appended blank lines are included in line numbers and lineCount. |
showLineNumbers | boolean | No | Whether to show line numbers. Defaults to true. |
showLanguageIcon | boolean | No | Whether to show the language icon. Defaults to true. |
showAvatar | boolean | No | Whether to show an avatar in the bottom-right corner of the code window. Defaults to false. |
avatarUrl | string | No | Avatar URL. When showAvatar is true, the server proxies it into base64; omit it to use the current API user's avatar. |
avatarSize | integer | No | Avatar width and height in px. Defaults to 26; range 24-128. |
avatarRadius | integer | No | Avatar corner radius in px. Defaults to 64; range 0-64. |
quality | integer | No | Output pixel-density multiplier from 1 to 3. Defaults to 1. |
source | "api" | "try-it-*" | No | Render source label. API calls should use api, which is the default. |
responseType | "json" | "image" | "cdnUrl" | No | Response type. json returns the normal JSON payload, image returns raw bytes, and cdnUrl is Pro/Admin only: it uploads to R2/S3-compatible storage then returns a CDN URL. |
returnImage | boolean | No | Legacy image response switch. Prefer responseType: "image" for new integrations. |
Response
With responseType=json, a successful response includes dataUrl and imageBase64, plus the resolved format, language, theme, dimensions, and recordId. With responseType=image, the response body is the image bytes and Content-Type is image/webp, image/png, or image/jpeg. With responseType=cdnUrl, the response includes cdnUrl, imageMd5, storageKey, uploaded, and basic metadata.
Tune parameters in Playground first
Use Playground to tune the theme, background, window size, export format, and other details until the result feels right. Then copy the parameters in one click and give that JSON to an AI so it can build your own workflow, Codex skill, or MCP calling script around stable settings.
Tune in Playground ↗Examples
const origin = process.env.CODIA_ORIGIN ?? "http://localhost:3000";
const token = process.env.CODIA_TOKEN;
const response = await fetch(origin + "/v1/code/render", {
method: "POST",
headers: {
Authorization: "Bearer " + token,
"Content-Type": "application/json",
},
body: JSON.stringify({
code: 'const message = "Hello, Codia";\\nconsole.log(message);',
language: "typescript",
format: "png",
theme: "github-dark",
filename: "app.ts",
quality: 2,
}),
});
if (!response.ok) throw new Error(await response.text());
const { dataUrl } = await response.json();
console.log(dataUrl);import os
import requests
origin = os.getenv("CODIA_ORIGIN", "http://localhost:3000")
token = os.environ["CODIA_TOKEN"]
response = requests.post(
origin + "/v1/code/render",
headers={
"Authorization": "Bearer " + token,
"Content-Type": "application/json",
},
json={
"code": 'const message = "Hello, Codia";\\nconsole.log(message);',
"language": "typescript",
"format": "png",
"theme": "github-dark",
"quality": 2,
},
)
response.raise_for_status()
print(response.json()["dataUrl"])package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
origin := os.Getenv("CODIA_ORIGIN")
if origin == "" {
origin = "http://localhost:3000"
}
token := os.Getenv("CODIA_TOKEN")
body := []byte("{\"code\":\"const message = \\\"Hello, Codia\\\";\\\\nconsole.log(message);\",\"language\":\"typescript\",\"format\":\"png\",\"theme\":\"github-dark\",\"quality\":2}")
req, err := http.NewRequest(http.MethodPost, origin+"/v1/code/render", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
if res.StatusCode < 200 || res.StatusCode >= 300 {
message, _ := io.ReadAll(res.Body)
panic(string(message))
}
data, _ := io.ReadAll(res.Body)
fmt.Println(string(data))
}<?php
$origin = getenv('CODIA_ORIGIN') ?: 'http://localhost:3000';
$token = getenv('CODIA_TOKEN');
$payload = json_encode([
'code' => 'const message = "Hello, Codia";\\nconsole.log(message);',
'language' => 'typescript',
'format' => 'png',
'theme' => 'github-dark',
'quality' => 2,
]);
$ch = curl_init($origin . '/v1/code/render');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $token,
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
if ($response === false || curl_getinfo($ch, CURLINFO_HTTP_CODE) >= 300) {
throw new RuntimeException(curl_error($ch) ?: $response);
}
curl_close($ch);
echo json_decode($response, true)['dataUrl'] . PHP_EOL;require "json"
require "net/http"
require "uri"
origin = ENV.fetch("CODIA_ORIGIN", "http://localhost:3000")
token = ENV.fetch("CODIA_TOKEN")
uri = URI.join(origin, "/v1/code/render")
request = Net::HTTP::Post.new(uri)
request["Authorization"] = "Bearer #{token}"
request["Content-Type"] = "application/json"
request.body = {
code: 'const message = "Hello, Codia";\\nconsole.log(message);',
language: "typescript",
format: "png",
theme: "github-dark",
quality: 2,
}.to_json
response = Net::HTTP.start(uri.hostname, uri.port) { |http| http.request(request) }
raise response.body unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)["dataUrl"]import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
String origin = System.getenv().getOrDefault("CODIA_ORIGIN", "http://localhost:3000");
String token = System.getenv("CODIA_TOKEN");
String body = """
{"code":"const message = \\"Hello, Codia\\";\\nconsole.log(message);","language":"typescript","format":"png","theme":"github-dark","quality":2}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(origin + "/v1/code/render"))
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() / 100 != 2) throw new RuntimeException(response.body());
System.out.println(response.body());using System.Net.Http.Headers;
using System.Text;
var origin = Environment.GetEnvironmentVariable("CODIA_ORIGIN") ?? "http://localhost:3000";
var token = Environment.GetEnvironmentVariable("CODIA_TOKEN");
using var client = new HttpClient();
using var request = new HttpRequestMessage(HttpMethod.Post, origin + "/v1/code/render");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{"code":"const message = \"Hello, Codia\";\\nconsole.log(message);","language":"typescript","format":"png","theme":"github-dark","quality":2}
""", Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());