crawlbaseDocs
Log in

API usage

Add &scraper=exercism-solution to a Crawling API request. URL-encode the target URL in the url parameter.

curl 'https://api.crawlbase.com/?token=YOUR_TOKEN' \
  --data-urlencode 'url=https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop' \
  --data-urlencode 'scraper=exercism-solution' -G
from crawlbase import CrawlingAPI

api = CrawlingAPI({'token': 'YOUR_TOKEN'})
res = api.get(
    'https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop',
    {'scraper': 'exercism-solution'}
)

import json
data = json.loads(res['body'])
const { CrawlingAPI } = require('crawlbase');
const api = new CrawlingAPI({ token: 'YOUR_TOKEN' });

const res = await api.get(
  'https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop',
  { scraper: 'exercism-solution' }
);
const data = JSON.parse(res.body);
require 'crawlbase'
api = Crawlbase::API.new(token: 'YOUR_TOKEN')

res = api.get('https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop', scraper: 'exercism-solution')
data = JSON.parse(res.body)

Example input URL

Any single published Exercism solution page works in the url parameter - the page at /tracks/<track>/exercises/<slug>/solutions/<handle>. For example:

https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop
https://exercism.org/tracks/go/exercises/hello-world/solutions/erikschierboom

Response shape

JSON response body. Field types may be null when the source page omits the value.

url
string
URL of the solution page that was scraped.
track
object
Track the solution belongs to.
track.slug
string | null
Track slug (for example ruby).
track.title
string | null
Track display title (for example Ruby).
track.iconUrl
string | null
URL of the track icon.
exercise
object
Exercise the solution belongs to.
exercise.slug
string | null
Exercise slug (for example two-fer).
exercise.type
string | null
Exercise type (for example practice or concept).
exercise.title
string | null
Exercise display title.
exercise.iconUrl
string | null
URL of the exercise icon.
exercise.difficulty
string | null
Difficulty label (for example easy, medium, hard).
exercise.blurb
string | null
Short exercise description.
author
object
Author of the solution.
author.handle
string | null
Author handle (Exercism username).
language
string | null
Programming language of the solution.
indentSize
integer | null
Editor indent size the author used, or null when not reported.
numStars
integer | null
Number of stars on the solution.
numIterations
integer
Number of iterations in the iterations array.
isOutOfDate
boolean
True when the solution is out of date with the current exercise.
publishedIterationIdx
integer | null
Index (idx) of the iteration that is published, or null when none.
publishedAt
string | null
Publish time of the solution (ISO 8601), or null when absent.
iterations
array
Iteration history for the solution, oldest first.
iterations[].idx
integer | null
Iteration index (1-based).
iterations[].status
string | null
Analysis status of the iteration (for example no_automated_feedback).
iterations[].testsStatus
string | null
Test run status of the iteration (for example passed).
iterations[].submissionMethod
string | null
How the iteration was submitted (for example cli or api).
iterations[].createdAt
string | null
Creation time of the iteration (ISO 8601), or null when absent.
iterations[].isPublished
boolean
True when this iteration is the published one.
iterations[].isLatest
boolean
True when this iteration is the most recent.
code
string | null
Full source code of the published solution, or null when absent.

Sample response

{
  "url": "https://exercism.org/tracks/ruby/exercises/two-fer/solutions/neilnorthrop",
  "track": {
    "slug": "ruby",
    "title": "Ruby",
    "iconUrl": "https://assets.exercism.org/tracks/ruby.svg"
  },
  "exercise": {
    "slug": "two-fer",
    "type": "practice",
    "title": "Two Fer",
    "iconUrl": "https://assets.exercism.org/exercises/two-fer.svg",
    "difficulty": "easy",
    "blurb": "Create a sentence of the form \"One for X, one for me.\""
  },
  "author": {
    "handle": "neilnorthrop"
  },
  "language": "ruby",
  "indentSize": 2,
  "numStars": 42,
  "numIterations": 2,
  "isOutOfDate": false,
  "publishedIterationIdx": 2,
  "publishedAt": "2026-05-18T14:03:27Z",
  "iterations": [
    {
      "idx": 1,
      "status": "no_automated_feedback",
      "testsStatus": "passed",
      "submissionMethod": "cli",
      "createdAt": "2026-05-17T22:41:03Z",
      "isPublished": false,
      "isLatest": false
    },
    {
      "idx": 2,
      "status": "no_automated_feedback",
      "testsStatus": "passed",
      "submissionMethod": "cli",
      "createdAt": "2026-05-18T14:03:27Z",
      "isPublished": true,
      "isLatest": true
    }
  ],
  "code": "def two_fer(name = \"you\")\n  \"One for #{name}, one for me.\"\nend"
}