Quickstart
Get an API key and make your first request with cURL or your preferred SDK.
Try a request
Create an account, then copy your key from the dashboard. Set it in the shell where you’ll run the example:export CONTEXT_DEV_API_KEY="ctxt_secret_..."
- Markdown
- Structured data
- Images
- Sitemap
- Brand
- Styleguide
- Batches
- Monitors
Turn a webpage into Markdown. This request costs 1 credit.Read page text from
curl --get https://api.context.dev/v1/web/scrape/markdown \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--data-urlencode "url=https://example.com" \
--data-urlencode "useMainContentOnly=true"
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const response = await client.web.webScrapeMd({
url: "https://example.com",
useMainContentOnly: true,
});
console.log(response.markdown);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.web.web_scrape_md(
url="https://example.com",
use_main_content_only=True,
)
print(response.markdown)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
response = client.web.web_scrape_md(
url: "https://example.com",
use_main_content_only: true,
)
puts response.markdown
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
"github.com/context-dot-dev/context-go-sdk/v2/packages/param"
)
func main() {
client := contextdev.NewClient(option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")))
response, err := client.Web.WebScrapeMd(context.Background(), contextdev.WebWebScrapeMdParams{
URL: "https://example.com",
UseMainContentOnly: param.NewOpt(true),
})
if err != nil {
panic(err)
}
fmt.Println(response.Markdown)
}
<?php
require __DIR__.'/vendor/autoload.php';
$client = new ContextDev\Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$response = $client->web->webScrapeMd(
url: "https://example.com",
useMainContentOnly: true,
);
echo $response->markdown, PHP_EOL;
markdown. The Markdown guide covers content filters and freshness.Extract a company fact into your JSON Schema, using up to 5 relevant pages. The 10-credit charge covers the full extraction, not each page.Read the extracted object from
curl https://api.context.dev/v1/web/extract \
--request POST \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"url": "https://stripe.com",
"schema": {
"type": "object",
"properties": {
"founded_year": {
"type": ["integer", "null"],
"description": "The year the company says it was founded. Return null if not stated."
}
},
"required": ["founded_year"],
"additionalProperties": false
},
"maxPages": 5,
"factCheck": true
}'
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const response = await client.web.extract({
url: "https://stripe.com",
schema: {
type: "object",
properties: {
founded_year: {
type: ["integer", "null"],
description:
"The year the company says it was founded. Return null if not stated.",
},
},
required: ["founded_year"],
additionalProperties: false,
},
maxPages: 5,
factCheck: true,
});
console.log(response.data, response.urls_analyzed);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.web.extract(
url="https://stripe.com",
schema={
"type": "object",
"properties": {
"founded_year": {
"type": ["integer", "null"],
"description": "The year the company says it was founded. Return null if not stated.",
},
},
"required": ["founded_year"],
"additionalProperties": False,
},
max_pages=5,
fact_check=True,
)
print(response.data, response.urls_analyzed)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
response = client.web.extract(
url: "https://stripe.com",
schema: {
"type" => "object",
"properties" => {
"founded_year" => {
"type" => ["integer", "null"],
"description" => "The year the company says it was founded. Return null if not stated.",
},
},
"required" => ["founded_year"],
"additionalProperties" => false,
},
max_pages: 5,
fact_check: true,
)
pp response.data, response.urls_analyzed
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
"github.com/context-dot-dev/context-go-sdk/v2/packages/param"
)
func main() {
client := contextdev.NewClient(option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")))
response, err := client.Web.Extract(context.Background(), contextdev.WebExtractParams{
URL: "https://stripe.com",
Schema: map[string]any{
"type": "object",
"properties": map[string]any{
"founded_year": map[string]any{
"type": []string{"integer", "null"},
"description": "The year the company says it was founded. Return null if not stated.",
},
},
"required": []string{"founded_year"},
"additionalProperties": false,
},
MaxPages: param.NewOpt(int64(5)),
FactCheck: param.NewOpt(true),
})
if err != nil {
panic(err)
}
fmt.Println(response.Data, response.URLsAnalyzed)
}
<?php
require __DIR__.'/vendor/autoload.php';
$client = new ContextDev\Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$response = $client->web->extract(
url: "https://stripe.com",
schema: [
"type" => "object",
"properties" => [
"founded_year" => [
"type" => ["integer", "null"],
"description" => "The year the company says it was founded. Return null if not stated.",
],
],
"required" => ["founded_year"],
"additionalProperties" => false,
],
maxPages: 5,
factCheck: true,
);
print_r([$response->data, $response->urlsAnalyzed]);
data and its source pages from urls_analyzed. See the extraction guide for schema design and fact checks.Find image sources referenced by a webpage. This request costs 1 credit.The
curl --get https://api.context.dev/v1/web/scrape/images \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--data-urlencode "url=https://stripe.com"
import ContextDev from "context.dev";
const client = new ContextDev({
apiKey: process.env.CONTEXT_DEV_API_KEY,
});
const page = await client.web.webScrapeImages({
url: "https://stripe.com",
});
console.log(page.images);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
page = client.web.web_scrape_images(url="https://stripe.com")
print(page.images)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
page = client.web.web_scrape_images(url: "https://stripe.com")
puts page.images
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
)
func main() {
client := contextdev.NewClient(
option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
)
page, err := client.Web.WebScrapeImages(context.Background(), contextdev.WebWebScrapeImagesParams{
URL: "https://stripe.com",
})
if err != nil {
panic(err)
}
fmt.Println(page.Images)
}
<?php
require __DIR__.'/vendor/autoload.php';
use ContextDev\Client;
$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$page = $client->web->webScrapeImages(url: 'https://stripe.com');
print_r($page->images);
images array contains the discovered assets; it may be empty. See the image guide for dimensions, hosted copies, and visual classification.List up to 50 customer-page URLs from Stripe’s public sitemaps without rendering each page. This request costs 1 credit.Read the URL list from
curl --get https://api.context.dev/v1/web/scrape/sitemap \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--data-urlencode "domain=stripe.com" \
--data-urlencode "maxLinks=50" \
--data-urlencode "urlRegex=/customers/"
import ContextDev from "context.dev";
const client = new ContextDev({
apiKey: process.env.CONTEXT_DEV_API_KEY,
});
const sitemap = await client.web.webScrapeSitemap({
domain: "stripe.com",
maxLinks: 50,
urlRegex: "/customers/",
});
console.log(sitemap.urls);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
sitemap = client.web.web_scrape_sitemap(
domain="stripe.com",
max_links=50,
url_regex="/customers/",
)
print(sitemap.urls)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
sitemap = client.web.web_scrape_sitemap(
domain: "stripe.com",
max_links: 50,
url_regex: "/customers/",
)
puts sitemap.urls
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
"github.com/context-dot-dev/context-go-sdk/v2/packages/param"
)
func main() {
client := contextdev.NewClient(
option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
)
sitemap, err := client.Web.WebScrapeSitemap(context.Background(), contextdev.WebWebScrapeSitemapParams{
Domain: "stripe.com",
MaxLinks: param.NewOpt[int64](50),
URLRegex: param.NewOpt("/customers/"),
})
if err != nil {
panic(err)
}
fmt.Println(sitemap.URLs)
}
<?php
require __DIR__.'/vendor/autoload.php';
use ContextDev\Client;
$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$sitemap = $client->web->webScrapeSitemap(
domain: 'stripe.com',
maxLinks: 50,
urlRegex: '/customers/',
);
print_r($sitemap->urls);
urls and check meta for sitemap fetches and errors. The sitemap guide covers filtering and discovery limits.Look up a company profile with logos, colors, descriptions, and social links. A successful lookup costs 10 credits.The matched company is in
curl https://api.context.dev/v1/brand/retrieve \
--request POST \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"type": "by_domain",
"domain": "stripe.com"
}'
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const response = await client.brand.retrieve({
type: "by_domain",
domain: "stripe.com",
});
console.log(response.brand?.title);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.brand.retrieve(
type="by_domain",
domain="stripe.com",
)
print(response.brand.title if response.brand else None)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
response = client.brand.retrieve(
body: {
"type" => "by_domain",
"domain" => "stripe.com",
}
)
puts response.brand&.title
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
)
func main() {
client := contextdev.NewClient(option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")))
response, err := client.Brand.Get(context.Background(), contextdev.BrandGetParams{
OfByDomain: &contextdev.BrandGetParamsBodyByDomain{
Domain: "stripe.com",
},
})
if err != nil {
panic(err)
}
fmt.Println(response.Brand.Title)
}
<?php
require __DIR__.'/vendor/autoload.php';
$client = new ContextDev\Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
// Use the SDK's low-level request: its generated Brand helper cannot express this lookup.
$response = $client->request(
method: 'post',
path: 'brand/retrieve',
body: [
"type" => "by_domain",
"domain" => "stripe.com",
],
);
$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR);
echo $data['brand']['title'] ?? 'No match', PHP_EOL;
brand. PHP SDK 2.14.0 uses its low-level request method for this lookup. See the brand guide for lookup options and result fields.Extract observed colors, typography, and component styles. This request costs 10 credits.Inspect
curl --get https://api.context.dev/v1/web/styleguide \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--data-urlencode "domain=stripe.com" \
--data-urlencode "colorScheme=light"
import ContextDev from "context.dev";
const client = new ContextDev({
apiKey: process.env.CONTEXT_DEV_API_KEY,
});
const response = await client.web.extractStyleguide({
domain: "stripe.com",
colorScheme: "light",
});
console.log(response.styleguide?.colors);
console.log(response.styleguide?.typography.headings.h1);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.web.extract_styleguide(
domain="stripe.com",
color_scheme="light",
)
print(response.styleguide.colors)
print(response.styleguide.typography.headings.h1)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(
api_key: ENV.fetch("CONTEXT_DEV_API_KEY")
)
response = client.web.extract_styleguide(
domain: "stripe.com",
color_scheme: :light
)
puts response.styleguide.colors.inspect
puts response.styleguide.typography.headings.h1.inspect
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
)
func main() {
client := contextdev.NewClient(
option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")),
)
response, err := client.Web.ExtractStyleguide(
context.Background(),
contextdev.WebExtractStyleguideParams{
Domain: contextdev.String("stripe.com"),
ColorScheme: contextdev.WebExtractStyleguideParamsColorSchemeLight,
},
)
if err != nil {
panic(err)
}
fmt.Println(response.Styleguide.Colors)
fmt.Println(response.Styleguide.Typography.Headings.H1)
}
<?php
require __DIR__.'/vendor/autoload.php';
use ContextDev\Client;
$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$response = $client->web->extractStyleguide(
domain: 'stripe.com',
colorScheme: 'light',
);
var_dump($response->styleguide->colors);
var_dump($response->styleguide->typography->headings->h1);
styleguide.colors and styleguide.typography. These are observations of the rendered page, not an official design-system specification. See the styleguide guide for the full result.Submit two URLs for background scraping. Each successful page costs 1 credit.The response contains a job
curl https://api.context.dev/v1/batch/submit \
--request POST \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"input": {
"mode": "scrape",
"data": {
"format": "markdown",
"urls": [
{
"url": "https://docs.context.dev/introduction"
},
{
"url": "https://docs.context.dev/quickstart"
}
]
}
}
}'
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const response = await client.batch.submit({
input: {
mode: "scrape",
data: {
format: "markdown",
urls: [
{
url: "https://docs.context.dev/introduction",
},
{
url: "https://docs.context.dev/quickstart",
},
],
},
},
});
console.log(response.id);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.batch.submit(
input={
"mode": "scrape",
"data": {
"format": "markdown",
"urls": [
{
"url": "https://docs.context.dev/introduction",
},
{
"url": "https://docs.context.dev/quickstart",
},
],
},
},
)
print(response.id)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
response = client.batch.submit(
input: {
mode: "scrape",
data: {
format: "markdown",
urls: [
{
url: "https://docs.context.dev/introduction",
},
{
url: "https://docs.context.dev/quickstart",
},
],
},
},
)
puts response.id
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
)
func main() {
client := contextdev.NewClient(option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")))
response, err := client.Batch.Submit(context.Background(), contextdev.BatchSubmitParams{
Input: contextdev.BatchSubmitParamsInputUnion{
OfScrape: &contextdev.BatchSubmitParamsInputScrape{
Mode: "scrape",
Data: contextdev.BatchSubmitParamsInputScrapeDataUnion{
OfMarkdown: &contextdev.BatchSubmitParamsInputScrapeDataMarkdown{
Format: "markdown",
URLs: []contextdev.BatchSubmitParamsInputScrapeDataMarkdownURL{
contextdev.BatchSubmitParamsInputScrapeDataMarkdownURL{
URL: "https://docs.context.dev/introduction",
},
contextdev.BatchSubmitParamsInputScrapeDataMarkdownURL{
URL: "https://docs.context.dev/quickstart",
},
},
},
},
},
},
})
if err != nil {
panic(err)
}
fmt.Println(response.ID)
}
<?php
require __DIR__.'/vendor/autoload.php';
use ContextDev\Client;
$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$response = $client->batch->submit(
input: [
"mode" => "scrape",
"data" => [
"format" => "markdown",
"urls" => [
[
"url" => "https://docs.context.dev/introduction",
],
[
"url" => "https://docs.context.dev/quickstart",
],
],
],
],
);
echo $response->id, PHP_EOL;
id, not completed page content. Save it, then poll for completion and read the results.Check a pricing page for text changes every day. No webhook is required.Save
curl https://api.context.dev/v1/monitors \
--request POST \
--header "Authorization: Bearer $CONTEXT_DEV_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Pricing changes",
"target": {
"type": "page",
"url": "https://stripe.com/pricing",
"normalize_whitespace": true
},
"change_detection": {
"type": "exact"
},
"schedule": {
"type": "interval",
"frequency": 1,
"unit": "days"
}
}'
import ContextDev from "context.dev";
const client = new ContextDev({ apiKey: process.env.CONTEXT_DEV_API_KEY });
const response = await client.monitors.create({
name: "Pricing changes",
target: {
type: "page",
url: "https://stripe.com/pricing",
normalize_whitespace: true,
},
change_detection: {
type: "exact",
},
schedule: {
type: "interval",
frequency: 1,
unit: "days",
},
});
console.log(response.id, response.initial_run_id);
import os
from context.dev import ContextDev
client = ContextDev(api_key=os.environ["CONTEXT_DEV_API_KEY"])
response = client.monitors.create(
name="Pricing changes",
target={
"type": "page",
"url": "https://stripe.com/pricing",
"normalize_whitespace": True,
},
change_detection={
"type": "exact",
},
schedule={
"type": "interval",
"frequency": 1,
"unit": "days",
},
)
print(response.id, response.initial_run_id)
require "cgi/core"
require "context_dev"
client = ContextDev::Client.new(api_key: ENV.fetch("CONTEXT_DEV_API_KEY"))
response = client.monitors.create(
name: "Pricing changes",
target: {
type: "page",
url: "https://stripe.com/pricing",
normalize_whitespace: true,
},
change_detection: {
type: "exact",
},
schedule: {
type: "interval",
frequency: 1,
unit: "days",
},
)
puts response.id, response.initial_run_id
package main
import (
"context"
"fmt"
"os"
contextdev "github.com/context-dot-dev/context-go-sdk/v2"
"github.com/context-dot-dev/context-go-sdk/v2/option"
)
func main() {
client := contextdev.NewClient(option.WithAPIKey(os.Getenv("CONTEXT_DEV_API_KEY")))
response, err := client.Monitors.New(context.Background(), contextdev.MonitorNewParams{
Name: "Pricing changes",
Target: contextdev.MonitorNewParamsTargetUnion{
OfPage: &contextdev.MonitorNewParamsTargetPage{
Type: "page",
URL: "https://stripe.com/pricing",
NormalizeWhitespace: contextdev.Bool(true),
},
},
ChangeDetection: contextdev.MonitorNewParamsChangeDetectionUnion{
OfExact: &contextdev.MonitorNewParamsChangeDetectionExact{
Type: "exact",
},
},
Schedule: contextdev.MonitorNewParamsSchedule{
Type: "interval",
Frequency: 1,
Unit: "days",
},
})
if err != nil {
panic(err)
}
fmt.Println(response.ID, response.InitialRunID)
}
<?php
require __DIR__.'/vendor/autoload.php';
use ContextDev\Client;
$client = new Client(apiKey: getenv('CONTEXT_DEV_API_KEY'));
$response = $client->monitors->create(
name: "Pricing changes",
target: [
"type" => "page",
"url" => "https://stripe.com/pricing",
"normalizeWhitespace" => true,
],
changeDetection: [
"type" => "exact",
],
schedule: [
"type" => "interval",
"frequency" => 1,
"unit" => "days",
],
);
echo $response->id, " ", $response->initialRunID, PHP_EOL;
id and initial_run_id. The first run establishes a baseline. Use the monitoring guide to read later runs and changes.Explore the APIs
Web data APIs
Scrape Markdown
Turn a webpage into Markdown for agents, search, and retrieval.
Scrape HTML
Retrieve page HTML to parse and process yourself.
Structured extraction
Combine fields from relevant pages into one object matching your JSON Schema.
Crawl
Follow website links and return each page as Markdown.
Web search
Search the web and optionally scrape result pages in the same call.
Sitemap
Discover URLs in public sitemaps before fetching page content.
Images
Extract image assets from a webpage, with optional metadata enrichment.
Screenshots
Capture a webpage as an image.
Document parsing
Convert PDFs, Office documents, images, and other supported files into Markdown.
Brand data APIs
Brand lookup
Retrieve company logos, colors, descriptions, social links, and industry tags where available.
Brand search
Find indexed brands by name or domain prefix for autocomplete.
Simplified brand data
Get a smaller brand response with a domain, title, colors, logos, and backdrops.
Styleguide
Extract a website’s colors, typography, spacing, and component styles.
Fonts
Identify a website’s font families, fallbacks, and usage.
Logo Link
Embed a company logo directly using a separate public client ID.
NAICS classification
Classify a company using 2022 NAICS industry codes.
SIC classification
Classify a company using original SIC codes or the SEC’s current list.
Company and product data
Product extraction
Extract pricing, images, descriptions, and other details from one product page.
Product discovery
Discover and extract up to 12 products from a website. Available in beta.
People enrichment
Match identity clues to a person profile with a match score. Beta, paid plans.
Company news
Find current and historical company news by name, domain, ticker, or ISIN.
Company funding
Retrieve known funding rounds, dates, and amounts by company domain.
Automation and utilities
Batches
Process URL lists or website crawls asynchronously and retrieve the results.
Monitors
Track changes to pages, sitemaps, or structured data and receive signed webhooks.
Prefetch
Warm brand or styleguide caches before you need the data. Paid subscription required.
Before you ship
Context.dev is a hosted API, with SDKs for TypeScript, Python, Ruby, Go, and PHP. There is no self-hosted edition. Scraping can render JavaScript, but a login wall or bot challenge can still prevent access. Markdown results may come from a cache up to one day old by default; setmaxAgeMs=0 when you need a new fetch. Other endpoints have their own freshness rules.
Each guide explains its costs, limits, and failure cases.
API reference
Check the request parameters and response fields for each endpoint.
Production checklist
Plan retries, data handling, and deployment behavior.