---
title: "Code Screenshot API: Render Highlighted Snippets to PNG"
description: "Use the Code Screenshot API to convert source snippets into themed images. POST code, language, and theme; get a 1600x1000 PNG with window chrome."
url: "https://html2img.com/templates/code-screenshot/"
---

# Code Screenshot API

Send the snippet, language, and theme name as JSON, get back a syntax-highlighted PNG.

Developer educators and DevRel teams use the Code Screenshot API to share polished snippets without screenshotting their editor and dragging the result into Figma. Server-side highlighting via scrivo/highlight.php means there is no JS race or font-loading ambiguity, so the same input produces the same output every time. You post the code, language, and theme name as JSON, and the response holds a PNG with window chrome and a themed background.

## At a glance

- **Template slug:** `code-screenshot`
- **Category:** developer
- **Endpoint:** `POST https://app.html2img.com/api/v1/templates/code-screenshot`
- **Authentication:** `X-API-Key` header
- **Cost:** one credit per render, PNG or PDF
- **Page:** https://html2img.com/templates/code-screenshot/

## Fields

| Field | Type | Required | Example |
| --- | --- | --- | --- |
| `code` | string | Yes | export async function fetchUser(id: string) { const res = await fetch(`/api/users/${id}`); if (!res.ok) { throw new Err… |
| `language` | string | No | typescript |
| `title` | string | No | src/lib/users.ts |
| `theme` | string | No | atom-one-dark |
| `background` | string | No | linear-gradient(135deg, #6366F1 0%, #8B5CF6 50%, #EC4899 100%) |
| `padding` | number | No | 72 |
| `show_window_chrome` | enum (true, false) | No | true |
| `show_line_numbers` | enum (true, false) | No | false |

## Defaults

| Field | Default |
| --- | --- |
| `width` | 1600 |
| `height` | 1000 |

## Example request

```bash
curl -X POST https://app.html2img.com/api/v1/templates/code-screenshot \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"export async function fetchUser(id: string) {\n  const res = await fetch(`/api/users/${id}`);\n\n  if (!res.ok) {\n    throw new Error(`Failed to load user ${id}`);\n  }\n\n  return res.json() as Promise<User>;\n}","language":"typescript","title":"src/lib/users.ts","theme":"atom-one-dark","background":"linear-gradient(135deg, #6366F1 0%, #8B5CF6 50%, #EC4899 100%)","padding":72,"show_window_chrome":"true","show_line_numbers":"false"}'
```

## In your language

### PHP

```php
<?php
$response = \Illuminate\Support\Facades\Http::withHeaders([
    'X-API-Key' => 'YOUR_API_KEY',
])->post('https://app.html2img.com/api/v1/templates/code-screenshot', ['code' => 'export async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);

  if (!res.ok) {
    throw new Error(`Failed to load user ${id}`);
  }

  return res.json() as Promise<User>;
}', 'language' => 'typescript', 'title' => 'src/lib/users.ts', 'theme' => 'atom-one-dark', 'background' => 'linear-gradient(135deg, #6366F1 0%, #8B5CF6 50%, #EC4899 100%)', 'padding' => 72, 'show_window_chrome' => 'true', 'show_line_numbers' => 'false']);

$url = $response->json('url');
```

### Node.js

```javascript
const response = await fetch('https://app.html2img.com/api/v1/templates/code-screenshot', {
  method: 'POST',
  headers: {
    'X-API-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "code": "export async function fetchUser(id: string) {\n  const res = await fetch(`/api/users/${id}`);\n\n  if (!res.ok) {\n    throw new Error(`Failed to load user ${id}`);\n  }\n\n  return res.json() as Promise<User>;\n}",
    "language": "typescript",
    "title": "src/lib/users.ts",
    "theme": "atom-one-dark",
    "background": "linear-gradient(135deg, #6366F1 0%, #8B5CF6 50%, #EC4899 100%)",
    "padding": 72,
    "show_window_chrome": "true",
    "show_line_numbers": "false"
}),
});

const { url } = await response.json();
```

### Python

```python
import requests

response = requests.post(
    'https://app.html2img.com/api/v1/templates/code-screenshot',
    headers={'X-API-Key': 'YOUR_API_KEY'},
    json={'code': 'export async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);

  if (!res.ok) {
    throw new Error(`Failed to load user ${id}`);
  }

  return res.json() as Promise<User>;
}', 'language': 'typescript', 'title': 'src/lib/users.ts', 'theme': 'atom-one-dark', 'background': 'linear-gradient(135deg, #6366F1 0%, #8B5CF6 50%, #EC4899 100%)', 'padding': 72, 'show_window_chrome': 'true', 'show_line_numbers': 'false'},
)

url = response.json()['url']
```

## What it is for

### Developers sharing snippets on social

A staff engineer wants to post a 12-line TypeScript snippet on X and refuses to drag a screenshot of their editor through three crops. Pipe the code into a Raycast or Alfred action that posts to this endpoint and copies the resulting URL to the clipboard. The snippet posts to X with a styled card that reads at a glance in the timeline. Halberd Software's engineering team produces 30 snippets a week through this exact flow.

### Documentation sites embedding code blocks as images

Static docs that need to rank in image search benefit from rendered code blocks rather than raw <pre> elements. Generate one PNG per code block during the build, alt-text it, and embed alongside the regular HTML version. Both Google and Bing index the styled snippets, so a search for the API's exact function signature surfaces your docs page. Wren Analytics built this for its REST API reference and reports a 40 percent uplift in image-search traffic.

### Tutorial newsletters with styled code

Newsletter tools render monospaced code blocks inconsistently across Gmail, Outlook, and Apple Mail. Sidestep the layout drift by rendering each snippet as a PNG and embedding the URL in the email body. Subscribers see the same code on every client, with the same font and the same syntax colors. Linden & Co's weekly Laravel newsletter uses this pattern across 20 snippets per issue.

### Conference talk slides

Speakers presenting code on a 4K projector at the back of a 200-seat room need a snippet that reads from row 30. Render at 2x scale by setting dpi=2 in the render options and slot the resulting image into your slide deck. The Type Conference issued these to 28 speakers last year, and the talks looked uniformly polished even from the cheap seats.

### GitHub gist promotion

Gist authors can build a sharable preview that shows the code at the top of the gist page rather than relying on the user clicking through. Render with the gist title and language, post the resulting URL alongside the gist link, and the share previews on X and Slack show the actual code rather than a generic GitHub favicon. Northwind Studio's open source repo benefits from this on every gist link they publish.

## Output

- **Dimensions:** 1600x1000
- **Colour space:** sRGB
- **Transparency:** Supported
- **Typical file size:** 40 KB to 150 KB
- **Platform specification:** [Developer share format with optional transparent canvas](https://highlightjs.org/)

## Common mistakes

### Line wrapping on long lines breaks intent

A 140-character line wraps to two visual rows and the reader loses the structure of the code. Refactor to shorter lines, or set a wider canvas via the width override so long lines fit on one row.

### Choosing a theme that does not exist

You pass theme="vscode-dark-pro" and the render falls back to atom-one-dark because that theme name is not in the highlight.php styles directory. Pick from the documented list (atom-one-dark, dracula, monokai, nord, github-dark, etc.) so the render matches your design intent.

### Padding too small leaves chrome touching the edge

A 16-pixel padding squeezes the window chrome against the canvas edge and the result looks cramped. Set padding to at least 48 pixels, or 72 for a more editorial feel, so the snippet has breathing room within the frame.

## Questions

### Which languages are supported?

All languages supported by highlight.php (a port of highlight.js): JavaScript, TypeScript, Python, Ruby, Go, Rust, PHP, Java, C, C++, C#, Swift, Kotlin, HTML, CSS, SQL, YAML, JSON, Bash, and many more. Pass the language slug as the language input.

### Which themes are available?

Any theme slug from the highlight.php styles directory. Common picks: atom-one-dark, atom-one-light, dracula, github-dark, github-light, monokai, nord, solarized-dark, solarized-light. Unknown theme names fall back to atom-one-dark.

### Can I hide the window chrome?

Yes, set show_window_chrome to "false" and the traffic-light header is omitted. Useful for embedding inside a slide deck or document where the chrome would feel redundant. The padding and rounded corner of the code surface remain.

### Can I show line numbers?

Yes, set show_line_numbers to "true". The numbers render in a muted weight on the left side of the code surface. They help reviewers reference specific lines but add visual noise, so default is off.

### How do I match dimensions to my code?

Leave width and height unset and the renderer fits the content automatically. Set padding to control breathing room around the code surface. For a fixed canvas (slides or social), set both dimensions and let the code surface scale within them.

### How does this compare to carbon.now.sh?

Carbon is a manual web tool you use one snippet at a time. This is an HTTP endpoint that returns a hosted PNG URL for programmatic use, which means you can render hundreds of snippets in CI or from a script. The visual style is comparable, but the workflow is automated.

## Preview

![Code Screenshot API example render](https://i.html2img.com/image-1777560099683-150680.png)

## Related templates

- [github-social-preview](https://html2img.com/templates/github-social-preview/)
- [project-showcase](https://html2img.com/templates/project-showcase/)

## See also

- [Every template](https://html2img.com/templates/)
- [Templates API reference](https://html2img.com/docs/templates/)
- [OpenAPI specification](https://html2img.com/openapi.json)
