API

Serpel REST API reference

The Serpel REST API under https://serpel.app/api/v1 offers the same features as the dashboard and the CLI, as JSON over HTTPS. You authenticate with an API token that carries permissions called scopes. This page lists the scopes, errors, rate limits, credit rules and every endpoint, and ends with curl examples.

What is the base URL of the Serpel API?

All endpoints live under https://serpel.app/api/v1. Paths in this reference are relative to it, so /projects means https://serpel.app/api/v1/projects. Requests and responses use JSON. Send Content-Type: application/json with a body. GET https://serpel.app/api/v1 returns a machine-readable index of the endpoints without authentication, and GET https://serpel.app/api/health returns the service status.

How do you authenticate with the API?

Send an API token as a bearer token. Tokens start with vsk_. Create one in the dashboard under Settings, API tokens, with serpel tokens create or with POST /tokens.

HTTP
GET /api/v1/projects HTTP/1.1
Host: serpel.app
Authorization: Bearer vsk_your_token
  • A token can only call endpoints whose scope it has. Without it, the API answers with 403 forbidden.
  • The project role still applies: viewers read, editors change, owners manage members and delete the project.
  • The dashboard uses a session cookie instead of a token. Cookie requests that change data must come from the Serpel origin.
  • OAuth access tokens issued to MCP clients only work at the MCP server. The REST API rejects them with 403 forbidden.

Which scopes can an API token have?

Serpel has 18 scopes. Choose the smallest set that your integration needs.

ScopeLabel in the dashboardWhat it allows
projects:readRead projectsRead projects, overviews, members, reports, search data, web analytics, conversions and integrations.
projects:writeCreate and edit projectsCreate, change and delete projects and members, connect search data, web analytics and integrations, and manage report recipients and webhooks.
keywords:readRead keyword listsRead keyword lists, their keywords and saved research runs.
keywords:writeResearch keywords and edit listsRun keyword research (uses credits), create and change keyword lists, import keywords and refresh metrics.
audit:readRead crawls and issuesRead crawls, pages, issues, comparisons and Core Web Vitals.
audit:writeStart crawlsStart crawls.
rankings:readRead rankingsRead tracked keywords, rank history, stored search results, competitors, AI prompts and AI visibility.
rankings:writeTrack keywords and start rank checksTrack and remove keywords, start rank checks, AI checks and monitoring runs, and manage competitors and AI prompts.
tasks:readRead tasksRead tasks.
tasks:writeCreate and edit tasksCreate, change and delete tasks.
export:readExport dataExport issues, keywords, rankings and tasks.
billing:readRead balance and usageRead balance, usage, the credit ledger, the plan and the agent spending settings, and estimate costs.
billing:writeTop up balanceStart checkouts, change or cancel the subscription and change the agent spending settings. Workspace owners only.
codebase:readRead codebase snapshotsRead codebase snapshots.
codebase:writeUpload codebase snapshotsUpload codebase snapshots.
recommendations:readRead recommendationsRead recommendations.
recommendations:writeAccept, dismiss and complete recommendationsAccept, dismiss, complete and reopen recommendations.
mcp:readUse the MCP server (read-only)Use the MCP server, read-only. The REST API does not need this scope.

Restrict a token to projects

A token can be limited to a list of projects with projectIds. Such a token sees only those projects. A project outside the list answers with 404 not_found, as if it did not exist, and lists leave it out. Tokens can also expire after 1 to 365 days.

Create a restricted token
curl -X POST https://serpel.app/api/v1/tokens \
  -H "Authorization: Bearer $SERPEL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "CI crawl", "scopes": ["projects:read", "audit:read", "audit:write"], "projectIds": ["0b6f0f0e-6d1a-4c8e-9a53-4f9d2d7b8a10"], "expiresInDays": 90}'

In the response, token holds the metadata and secret holds the token itself. The secret is shown exactly once. Creating tokens needs a token with all permissions. A token restricted to projects can only create tokens for its own projects.

What do responses and pagination look like?

JSON
{ "data": { } }

{ "data": [ ], "pagination": { "limit": 50, "offset": 0, "total": 123 } }

Single objects come in data. Lists add pagination. Lists accept limit (1 to 200, default 50), offset (from 0) and usually q to search. Every response carries an X-Request-ID header. You can send your own X-Request-ID (up to 128 letters, digits, ., _, : and -) and quote the value when you contact support.

How does the API report errors?

Validation error for an empty domain (HTTP 400)
{
  "error": {
    "code": "validation_error",
    "message": "Enter a domain.",
    "details": [{ "path": "domain", "message": "Enter a domain." }]
  }
}
HTTPCodeMeaning
400validation_errorThe input is invalid. details lists path and message for each problem.
400bad_requestThe request is malformed, for example invalid JSON or a body over 2.5 MB.
400authorization_pending, slow_down, expired_token, access_deniedAnswers of the device login at POST /auth/device/token.
401unauthorizedThe token is missing, invalid, expired or revoked.
402insufficient_creditsNot enough credits. details has balance, available and required.
403forbiddenA scope or role is missing, an OAuth token was used on the REST API, or the workspace is blocked from paid operations.
403plan_limitThe plan’s limits are exceeded: projects, tracked keywords, AI prompts or daily monitoring. details has plan and limits.
404not_foundThe item does not exist or the token cannot see it.
409conflictThe state does not allow it, for example a project that already exists (details.existingProjectId).
429rate_limitedToo many requests. The Retry-After header and details.retryAfterSeconds tell you how long to wait.
429budget_exceededThe workspace’s daily credit limit or a provider budget is reached.
500internal_errorAn error on the server. Retry later and quote the X-Request-ID.
502provider_errorA data provider failed or could not be reached.
503provider_not_configuredThe data provider for this feature is not set up.

What are the API rate limits?

LimitApplies toWindow
600 requestsEach API token, for all endpoints.One minute
30 operationsEach workspace, for crawls, rank checks, AI checks, monitoring runs, keyword research and list refreshes.One minute
20 requestsEach IP address, for all free tool endpoints under /tools/, which need no token.10 minutes
200 requestsEach IP address, for all free tool endpoints under /tools/.One day

When you exceed a limit, the API answers with HTTP 429 and rate_limited. Wait for the seconds in the Retry-After header, then continue. The MCP server has its own limit, described in the Claude Code guide.

How do idempotency keys work?

POST /keywords/research and POST /keyword-lists/{id}/refresh use credits and answer synchronously. Add an Idempotency-Key header with up to 200 letters, digits and the characters ., _, : and - to make a retry safe. A repeated request with the same key does not call the data provider again and does not book credits again. Without the header, the server generates a random key, which protects nothing on a retry. The CLI creates a key for you and accepts --idempotency-key.

How do credits work in the API?

Reading data is free. These operations use credits, at the prices of the dashboard:

OperationUnitCredits
Scheduled monitoring, up to top 50per keyword2
Scheduled monitoring, top 100per keyword3
Rank check right now, up to top 50per keyword5
Rank check right now, top 100per keyword9
ChatGPT answer checkper question2
Google AI Overview checkper question2
Keyword researchper search8 + 4 per 50 results
Keyword research by domainper domain4 + 2 per 50 results
Site crawlper 20 pages1

Estimate a cost first with POST /billing/estimate. It needs billing:read, books nothing and returns minCredits, maxCredits and a breakdown. Supported operations are rankCheck, aiCheck, keywordResearch, keywordListRefresh, keywordMetrics, crawl and monitoring.

Estimate a rank check
curl -X POST https://serpel.app/api/v1/billing/estimate \
  -H "Authorization: Bearer $SERPEL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"operation": "rankCheck", "params": {"keywordCount": 20, "depth": 50}}'

If the balance is too low for an operation, the API answers with HTTP 402.

Insufficient credits (HTTP 402)
{
  "error": {
    "code": "insufficient_credits",
    "message": "The available credits balance isn’t sufficient for this operation.",
    "details": { "balance": 3, "available": 3, "required": 12 }
  }
}

Which endpoints does the REST API have?

The groups below follow the index that GET /api/v1 returns. Path parameters appear in braces. Methods in one row share the path. The scope line above each table names the scopes the endpoints need.

Authentication

These endpoints serve the sign-up and sign-in screens of the dashboard and need no token. The Google endpoints are browser redirects, not JSON calls.

EndpointMethodsWhat it does
/auth/signupPOSTCreate an account with a personal workspace and send a confirmation email
/auth/verify-emailPOSTVerify the email address with a one-time token valid for 24 hours
/auth/password-reset/requestPOSTRequest a password reset without revealing whether an account exists
/auth/password-reset/confirmPOSTSet a new password with a one-time token valid for one hour
/auth/google/startGETStart signing in or signing up with Google as a browser redirect (query intent login, signup or reauthenticate, optional next path); creates a one-time state, PKCE verifier and nonce bound to a short-lived cookie
/auth/google/callbackGETReturn address of Google: checks state, cookie binding, code and ID token, then signs in, links the account by verified email address or asks for the terms; redirects to the dashboard or back to the sign-in page with an error code
/auth/google/completePOSTCreate the account after the first Google sign-in once the terms are accepted ({ acceptTerms: true }, cookie from the callback)
/cancellation-requestsPOSTCancel a subscription without signing in (§ 312k BGB), store the receipt with a timestamp and confirm it by email

Free tools

These endpoints need no token. They share one limit per IP address instead: 20 requests per 10 minutes and 200 per day. GET results are cached for a short time: 1 minute for the schema validator and the redirect checker, 5 minutes for the sitemap checker and 10 minutes for the robots.txt check.

EndpointMethodsWhat it does
/tools/robots-checkGETCheck without signing in which AI crawlers a domain’s robots.txt allows on the homepage, plus its llms.txt and sitemaps (domain query parameter)
/tools/schema-validateGET, POSTValidate JSON-LD, Microdata and RDFa without signing in. GET takes a public page URL (url query parameter) and reads its static HTML. POST takes a JSON body with a code field and checks pasted JSON-LD or HTML up to 512 KB. Returns the detected items by type with properties, errors and warnings with property paths, and Google rich result eligibility
/tools/redirect-checkGETTrace the redirect chain of a URL without signing in (url query parameter, optional userAgent: browser, googlebot, googlebotSmartphone, bingbot or gptbot). Returns every hop with status code, Location, response time and server header for up to 10 redirects, loop and downgrade detection, a meta refresh on the final page and recommendations
/tools/sitemap-checkGETValidate the XML sitemaps of a domain or a sitemap URL without signing in (url query parameter). Discovers sitemaps through robots.txt and the default locations, checks status, content type, gzip, XML, namespace, limits and entries of up to 10 child sitemaps, and samples the status of up to 20 listed URLs

Account

GET /me works with any valid token. Changing the profile and using /tokens need a token with all permissions. /account/export, /account/delete, /account/password/set and /account/identities/google need a dashboard session, not an API token.

EndpointMethodsWhat it does
/meGET, PATCHSigned-in user and token permissions; change name and email address
/account/exportGETDownload account data, workspace, projects, integrations and export links as JSON
/account/deletePOSTDelete the account with session and password, or, without a password, after a confirmation with Google from the last 10 minutes; permanent cleanup after 30 days
/account/securityGETSign-in methods of the account: password set or not, linked Google account, and whether a recent confirmation with Google is valid
/account/password/setPOSTSet the first password of an account that signed up with Google; needs a confirmation with Google from the last 10 minutes
/account/identities/googleDELETEUnlink the Google account; only possible when the account has a password
/tokensGET, POSTList and create API tokens
/tokens/{id}DELETERevoke a token
/providersGETData providers, daily budget, usage and last use
/favicons/{domain}GETLogo of a domain for the interface, fetched server-side and cached for 7 days

Billing

Reading needs billing:read. Checkouts and changes need billing:write and the workspace owner role.

EndpointMethodsWhat it does
/billing/summaryGETRead balance, daily limit and usage of the last 30 days
/billing/estimatePOSTEstimate the credit cost of an operation without booking it
/billing/ledgerGETRead the entries of the workspace credit ledger
/billing/checkout-sessionsPOSTCreate a Stripe Checkout for a credit pack or a custom amount
/billing/subscriptionGET, PATCHRead plan, limits and subscription or change the plan
/billing/subscription-sessionsPOSTCreate a Stripe Checkout for a Starter or Pro subscription
/billing/subscription/cancelPOSTCancel the subscription at the end of the billing period
/billing/subscription/resumePOSTUndo the cancellation of the subscription
/billing/portal-sessionsPOSTOpen the Stripe customer portal for payment details and invoices
/billing/agent-spendingGET, PATCHRead or change the “Agents can spend credits” setting with daily limit and today’s usage
/billing/stripe-webhookPOSTProcess signed Stripe events idempotently into payments and the credit ledger

MCP and connected apps

These endpoints need a dashboard session, or a token with all permissions for the two read and disconnect endpoints.

EndpointMethodsWhat it does
/oauth/consentPOSTDecide on an app’s OAuth request (session only, with CSRF token)
/oauth/appsGETApps connected via OAuth with workspace, permissions and last use
/oauth/apps/{id}DELETEDisconnect a connected app and revoke all its tokens

Projects

projects:read to read, projects:write to create and change. Changing a project needs the editor role, deleting it and managing members the owner role.

EndpointMethodsWhat it does
/projectsGET, POSTList and create projects
/projects/{id}GET, PATCH, DELETERead a project, change settings (including JavaScript rendering, Slack, Discord and custom webhook, channel name, search volume), delete it
/projects/{id}/overviewGETOverview with score, rankings, AI visibility and next steps
/projects/{id}/membersGET, POSTList and add members
/projects/{id}/exportGETExport issues, keywords, rankings or tasks as CSV or JSON

Audit

audit:read to read, audit:write to start crawls.

EndpointMethodsWhat it does
/projects/{id}/crawlsGET, POSTList and start crawls
/projects/{id}/crawls/compareGETCompare two crawls: new, fixed and changed issues
/projects/{id}/issuesGETIssues of the crawl with score and comparison
/projects/{id}/issues/{code}GETAffected URLs of an issue
/crawls/{id}GETRead a crawl, with statistics on rendering, link checks and Core Web Vitals
/crawls/{id}/pagesGETChecked URLs of a crawl, with HTML size and rendering flags
/crawls/{id}/pages/{pageId}GETA page with links, issues and signals (rendering, hreflang, structured data, soft 404)
/crawls/{id}/web-vitalsGETCore Web Vitals of the crawl from PageSpeed Insights: lab and field values per URL and device

Keywords and rankings

keywords:read and keywords:write for research and lists, rankings:read and rankings:write for tracked keywords and competitors. Research and list refreshes accept an Idempotency-Key header.

EndpointMethodsWhat it does
/keywords/researchGET, POSTStart keyword research with idempotency and credits; read the history with cost and duration
/keyword-listsGET, POSTManage keyword lists
/keyword-lists/{id}/refreshPOSTRefresh list metrics idempotently, billed in credits
/projects/{id}/rankingsGET, POSTList and add tracked keywords
/projects/{id}/rankings/runPOSTStart a ranking check right away
/rank-keywords/{id}/historyGETPosition history of a keyword
/rank-keywords/{id}/serpGETStored search results of the last check
/locationsGETSearch locations for local rank tracking
/projects/{id}/competitorsGET, POSTList and add competitors
/projects/{id}/competitors/overviewGETVisibility of you and your competitors
/projects/{id}/competitors/suggestionsGETCompetitor suggestions from the search results
/projects/{id}/competitors/comparisonGETPositions of you and your competitors, keyword by keyword

AI visibility and monitoring

rankings:read and rankings:write for AI visibility and monitoring runs, projects:read and projects:write for reports, recipients and webhooks.

EndpointMethodsWhat it does
/projects/{id}/ai-visibilityGETCitations in ChatGPT and Google AI Overviews, access for AI crawlers
/projects/{id}/ai-promptsGET, POSTList and create prompts for ChatGPT, each with the result of Google AI Overviews
/projects/{id}/ai-prompts/runPOSTCheck prompts right away, also in Google AI Overviews when the switch is on
/projects/{id}/monitoring/runPOSTStart monitoring with a report right away
/reportsGETReports, optionally only unread ones, with status and duration of the email delivery
/projects/{id}/report-recipientsGET, POSTEmail recipients of the reports and delivery status, with sandbox mode for Amazon SES
/projects/{id}/report-recipients/testPOSTSend a test email to the recipients
/reports/{id}/emailPOSTSend a report by email again
/reports/{id}/email-previewGETEmail of a report as HTML
/projects/{id}/webhook/testPOSTSend a test message to Slack, Discord and your own URL, or to a single target (channel)

Account integrations

projects:read to read, projects:write to connect, map and disconnect.

EndpointMethodsWhat it does
/integrationsGETGoogle, Bing, PostHog and Plausible with assignment per project
/integrations/google/authorizePOSTAuthorise Google for Search Console and Analytics
/integrations/{bing|posthog|plausible}POST, DELETEConnect with an API key or disconnect
/integrations/{provider}/syncPOSTReassign projects

Search data

projects:read to read, projects:write to connect and disconnect.

EndpointMethodsWhat it does
/projects/{id}/search-consoleGETConnections to Google Search Console and Bing Webmaster Tools
/projects/{id}/search-console/google/authorizePOSTCreate the authorisation URL for Google
/projects/{id}/search-console/bingPOSTConnect Bing Webmaster Tools with an API key
/projects/{id}/search-console/{provider}PATCH, DELETEChoose a property or disconnect
/projects/{id}/search-performanceGETClicks, impressions, CTR and position per query or page, from the stored history when it fully covers the period, otherwise live

Web analytics

projects:read to read, projects:write to connect and change.

EndpointMethodsWhat it does
/projects/{id}/analyticsGETConnections to PostHog, Plausible and Google Analytics
/projects/{id}/analytics/{provider}POSTConnect PostHog or Plausible with an API key
/projects/{id}/analytics/google_analytics/authorizePOSTCreate the authorisation URL for Google Analytics
/projects/{id}/analytics/{provider}PATCH, DELETEChoose a property or disconnect
/projects/{id}/analytics-reportGETVisitors, visits, bounce rate per day, top pages, entry pages, sources and devices
/projects/{id}/analytics/{provider}/conversion-eventsGET, PUTRead the provider’s events and choose the events that count as a conversion (at most 10)
/projects/{id}/conversionsGETSessions, conversions and conversion rate per entry page from the daily sync

Recommendations and codebase

recommendations:read and recommendations:write, codebase:read and codebase:write.

EndpointMethodsWhat it does
/projects/{id}/recommendationsGETRecommendations (“opportunities”) with impact, confidence, effort, evidence and data sources, filterable by status and rule
/recommendations/{id}GET, PATCHRead a recommendation, accept it, dismiss it, mark it as done or reopen it
/projects/{id}/codebase-snapshotsGET, POSTList and upload codebase snapshots (at most 2 MB, 20 per day and project, free of charge)
/codebase-snapshots/{id}GETSnapshot with routes, mapping to live pages, deviations and diff to the previous snapshot

Tasks and jobs

tasks:read and tasks:write for tasks. Jobs follow the scope of their type: audit:read for crawls, rankings:read for the other jobs.

EndpointMethodsWhat it does
/projects/{id}/tasksGET, POSTList and create tasks
/tasks/{id}GET, PATCH, DELETERead a task, change its status, delete it
/jobsGETRunning and finished background jobs
/jobs/{id}/cancelPOSTCancel a job
/projects/{id}/activityGETHistory of a project: jobs, reports by email and keyword research with duration and cost

More endpoints

These endpoints exist as well and are used by the CLI, but the index does not list them.

EndpointMethodsWhat it doesScope
/auth/devicePOSTStart a device login, as serpel auth login doesNo token
/auth/device/tokenPOSTExchange the device code for a token once the user approved itNo token
/auth/logoutPOSTRevoke the token that sends the requestAny valid token
/jobs/{id}GETRead one job with status, progress, result and last erroraudit:read for crawls, rankings:read for the other jobs
/jobs/{id}/retryPOSTRestart a failed or cancelled jobaudit:write for crawls, rankings:write for the other jobs
/projects/{id}/rankings/summaryGETTop 3, top 10, average position and changes of all tracked keywordsrankings:read
/rank-keywords/{id}DELETERemove a tracked keyword with its historyrankings:write
/projects/{id}/competitors/{competitorId}DELETERemove a competitorrankings:write
/ai-prompts/{id}/historyGETCheck history of a prompt for ChatGPT and Google AI Overviewsrankings:read
/ai-prompts/{id}DELETERemove a prompt with all its resultsrankings:write
/keywords/research/{runId}GETRead a saved research run without querying the providerkeywords:read
/keyword-lists/{id}GET, PATCH, DELETERead, rename or delete a keyword listkeywords:read to read, keywords:write to change
/keyword-lists/{id}/itemsGET, POSTList the keywords of a list or add keywordskeywords:read to read, keywords:write to add
/keyword-lists/{id}/items/{itemId}DELETERemove a keyword from a listkeywords:write
/keyword-lists/{id}/importPOSTImport keywords from CSV textkeywords:write
/keyword-lists/{id}/exportGETExport a keyword list as a CSV or JSON fileexport:read
/projects/{id}/members/{userId}DELETERemove a member from a projectprojects:write, owner role
/projects/{id}/report-recipients/{recipientId}DELETERemove an email recipient of the reportsprojects:write
/reports/{id}GETRead one reportprojects:read
/reports/{id}/readPOSTMark a report as readprojects:read
/reports/read-allPOSTMark all reports, or those of one project, as readprojects:read
/reports/unread-countGETNumber of unread reportsprojects:read
/projects/{id}/faviconGETWebsite icon of a project, fetched server-sideprojects:read

What do complete API examples look like?

The examples assume that SERPEL_TOKEN holds a token with the scopes named in each step. The responses are abridged to the fields you need next, and their values are illustrative. The real responses contain more fields.

Create a project

Needs projects:write. The API returns HTTP 201. If you already have a project for the domain, it answers with 409 conflict and the ID of the existing project in details.existingProjectId.

Terminal
curl -X POST https://serpel.app/api/v1/projects \
  -H "Authorization: Bearer $SERPEL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"domain": "example.com", "name": "Example", "country": "US", "language": "en"}'
Response (HTTP 201)
{
  "data": {
    "id": "0b6f0f0e-6d1a-4c8e-9a53-4f9d2d7b8a10",
    "name": "Example",
    "domain": "example.com",
    "country": "US",
    "language": "en",
    "role": "owner"
  }
}

Start a crawl and read the issues

Needs audit:write to start and audit:read to follow the job. The crawl runs in a worker, so the API answers with 202 and a job. If a crawl is already running, you get that crawl back with HTTP 200 and alreadyRunning: true. Poll GET /jobs/{id} until status is succeeded, failed or cancelled, then read the issues. maxPages can be 1 to 1000.

Terminal
curl -X POST https://serpel.app/api/v1/projects/$PROJECT_ID/crawls \
  -H "Authorization: Bearer $SERPEL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"maxPages": 200}'
Response (HTTP 202)
{
  "data": {
    "crawl": {
      "id": "7d2a4c1e-3b9f-4e0a-8c55-2f61b0a9d3e4",
      "status": "queued",
      "maxPages": 200,
      "pagesCrawled": 0
    },
    "job": {
      "id": "c41e8f27-5a6d-4b13-9d70-e8a2f4b6c915",
      "type": "crawl",
      "status": "queued"
    },
    "alreadyRunning": false
  }
}
Follow the job, then read the issues
curl https://serpel.app/api/v1/jobs/$JOB_ID \
  -H "Authorization: Bearer $SERPEL_TOKEN"

curl https://serpel.app/api/v1/projects/$PROJECT_ID/issues \
  -H "Authorization: Bearer $SERPEL_TOKEN"

Research keywords

Needs keywords:write and uses credits. A keyword research costs 8 credits plus 4 credits per block of 50 results, so 20 results cost 12 credits. The Idempotency-Key makes a retry safe. credits.charged and credits.balance show what the call cost and what is left.

Terminal
curl -X POST https://serpel.app/api/v1/keywords/research \
  -H "Authorization: Bearer $SERPEL_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: research-cold-brew-2026-10-10" \
  -d '{"mode": "keyword", "keyword": "cold brew concentrate", "country": "US", "language": "en", "limit": 20}'
Response (HTTP 200)
{
  "data": {
    "runId": "5e9b7a30-1c4d-4f82-b6a1-0d3c8e2f7a46",
    "mode": "keyword",
    "query": "cold brew concentrate",
    "country": "US",
    "language": "en",
    "cached": false,
    "items": [
      {
        "keyword": "cold brew concentrate",
        "relation": "seed",
        "searchVolume": 2900,
        "cpc": 1.45,
        "keywordDifficulty": 38,
        "intent": "commercial"
      }
    ],
    "credits": {
      "charged": 12,
      "balance": 488
    }
  }
}

Read rankings

Needs rankings:read. Each tracked keyword has its latest check and a change against the previous one; a positive change means the keyword moved up. A position of null with status ok means the page was not found within the checked depth.

Terminal
curl "https://serpel.app/api/v1/projects/$PROJECT_ID/rankings?limit=2&q=cold%20brew" \
  -H "Authorization: Bearer $SERPEL_TOKEN"
Response (HTTP 200)
{
  "data": [
    {
      "id": "a3f1c9d2-6b8e-4d57-9c20-7e4b1a5d8f03",
      "keyword": "cold brew concentrate",
      "country": "US",
      "language": "en",
      "device": "desktop",
      "searchVolume": 2900,
      "latest": {
        "checkedAt": "2026-10-09T06:00:12.000Z",
        "depth": 50,
        "position": 11,
        "url": "https://example.com/cold-brew-concentrate",
        "status": "ok"
      },
      "change": 3
    }
  ],
  "pagination": { "limit": 2, "offset": 0, "total": 1 }
}

Updated 10 Oct 2026

See also