Telephone
United States
+1 (800) 815 - 9959
12:00 PM - 5:00 PM (EST/EDT)
Monday - Friday
Need help?
Telephone
United States
United States
Canada
United Kingdom
Spain
France
Italy
Germany
Australia
+1 (800) 815 - 9959
12:00 PM - 5:00 PM (EST/EDT)
Monday - Friday
Semrush API version 4 includes:
Project API lets you get basic information about your Semrush projects, as well as perform some basic management actions (create, update, delete a project).
Listing Management API allows you to push data from your tools into Semrush Listing Management in bulk and distribute it across directories in seconds.
Map Rank Tracker API lets you access critical data related to your campaigns, keywords, and competitors. The methods provide detailed information about campaign rankings, heatmaps, competitors, and keyword performance. By easily integrating real-time data into your existing systems, you can stay ahead in your SEO strategies.
Semrush API version 4 is available only for the following Semrush tools and under specific conditions:
Semrush API supports authorization with the OAuth 2.0 flow. You need to pass your OAuth 2.0 authorization token in the HTTP request header:
Authorization: Bearer <TOKEN>
The Semrush API supports two ways to grant OAuth 2.0 credentials:
Use one of these options to authenticate in the Semrush API. The Device Authorization Grant flow is recommended.
This flow lets you, as an app or service developer, sign in with your own Semrush account so that your app can get Semrush API v4 data. This way, you can display the data from Semrush to your end-users without requiring those end-users to have Semrush accounts.
Unlike the standard Semrush Auth flow, you don't need to contact Semrush Customer Support and wait for your credentials.
Send a device authorization request to this endpoint:
POST https://oauth.semrush.com/dag/device/code
If the API requires scopes, include an optional scope=<scope>
parameter.
The authorization server responds with:
device_code
: Used by your application to poll the token endpoint.user_code
: Short code shown to you for sign-in.verification_uri
: Semrush sign-in page where you approve API access for your application.expires_in
: Seconds until the device/user codes expire (this is not the access token lifetime).interval
: Recommended polling interval in seconds.For most integrations, you sign in once to approve access and store the resulting tokens. You don't need to repeat this process unless the refresh token expires. If you're building a multi-tenant app where each tenant connects their own Semrush account, repeat this flow for each tenant during setup.
Response example (JSON)
{ "device_code": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "user_code": "YYYYYYYYYYY", "verification_uri": "https://oauth.semrush.com/dag/auth/verify_code?code=ZZZZZZZZZZZ", "expires_in": 300, "interval": 5 }
This sign-in step is performed by you, as the developer, not by your end-users.
verification_uri
in a browser.device_code
.While you complete Step 2, your application polls the token endpoint at the recommended interval until:
device_code
expires.Endpoint: POST https://oauth.semrush.com/dag/device/token
Required parameters:
grant_type = urn:ietf:params:oauth:grant-type:device_code
device_code =
Device verification code received in Step 1.Request example
curl https://oauth.semrush.com/dag/device/token \ -d device_code=7ee7a929306d4075b9c4020e584fe4508862f26605e37c131eb6efe2f83b6dd0 \ -d grant_type=urn:ietf:params:oauth:grant-type:device_code
Success response example (JSON)
{ "access_token": "e3wLk3PtqyVPHM7Ele61OhuZFWtKCFK4O1HQslzh", "token_type": "Bearer", "expires_in": 604800, "refresh_token": "YWza6vpqkW628wtMldRsQNalEu9k33Vg75PQiXGi" }
access_token
to call the Semrush API v4 and pull data into your system.expires_in
(7 days) and refresh the bearer token before it expires.refresh_token
securely to get new access tokens (valid for 30 days, refreshed along with the bearer token).If authorization fails or isn’t complete, the token endpoint returns an error as defined in RFC 6749, Section 5.2.
Generic error response format
{ "error": "<code>", "error_description": "<optional human-readable detail>" }
For possible errors and recommended actions, refer to the Status codes table.
client_id
and client_secret
.YOUR_CLIENT_ID
with your client_id
and open the link in your browser:https://oauth.semrush.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=%2Foauth2%2Fsuccess&response_type=code&scope=user.id
https://oauth.semrush.com/oauth2/success?code=UTyWR6YQAPUbtLIX9jWM4OifmK1ODVWDOVUt8hlk
.UTyWR6YQAPUbtLIX9jWM4OifmK1ODVWDOVUt8hlk
.Make a POST request using the value you copied as the code parameter value. In addition, replace YOUR_CLIENT_ID
and YOUR_CLIENT_SECRET
with the ones you received from Tech Support:
Note that the following request does not use json-body. Instead, the content type is application/x-www-form-urlencoded
.
Request example
curl -L 'https://oauth.semrush.com/oauth2/access_token' -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=YOUR_CLIENT_ID' -d 'client_secret=YOUR_CLIENT_SECRET' -d 'grant_type=authorization_code' -d 'code=YOUR_CODE' -d 'redirect_uri=%2Foauth2%2Fsuccess'
Response example (JSON)
{ "access_token": "wz1q0IpUBLLX7fqBKJI4pUoKBLZghAKp1VmBuJy5", "token_type": "Bearer", "expires_in": 604800, "refresh_token": "KTL5iInbFLIhm428FIKtHXO1ZX7ZUKNJTBoD9jk3" }
Use the access_token
value when making requests to the API. To get a new one when it expires, use refresh_token
:
Request example
curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=refresh_token&refresh_token=KTL5iInbFLIhm428FIKtHXO1ZX7ZUKNJTBoD9jk3" https://oauth.semrush.com/oauth2/access_token
Response example (JSON)
{ "access_token": "u8pPo6fo2NV70QCy7USWd3iT34CenBiT8RSuEEGn", "token_type": "Bearer", "expires_in": 604800, "refresh_token": "s99qrRuqbUdFRnum3R1HC9dTEJMOMs0IU1hJSi7W" }
The response body contains a JSON-encoded object, which has a top-level object called meta, followed by either a data object or an error object, but not both.
Key | Type | Description | Required/Optional |
---|---|---|---|
success | boolean | Request status | Required |
status_code | integer | HTTP status code | Required |
request_id | string | Unique ID of the request | Optional |
Success response example
{ "meta": { "success": true, "status_code": 200, "request_id": "IAD-as5656as776" }, "data": [ { "id": "590e", "kind": "dog", "name": "Penny" }, { "id": "a45f", "kind": "cat", "name": "Tommy" } ] }
Key | Type | Description | Required/Optional |
---|---|---|---|
code | integer | Error code | Required |
message | string | Error message | Required |
details | array | Error details | Optional |
Error response example
{ "meta": { "success": false, "status_code": 400, "request_id": "IAD-123ade456" }, "error": { "code": 120200, "message": "This was bad", "details": [ { "message": { "field_violations": [ { "field": "user_id", "description": "user_id must be a number" } ] } } ] } }
The API version 4 returns a corresponding HTTP status code with every request response, whether it succeeds or fails.
Code | Description | Recommended action |
---|---|---|
2XX OK | The request was processed successfully. | No action required. |
400 Bad Request | The request couldn't be processed because it was incorrect or incomplete. | Check the request body for typos and missing parameters. For details, refer to the optional 'error.details' field if it's present in the response. |
401 Unauthorized | The request couldn't be processed because the provided authentication credentials were incorrect or missing. | Ensure the access token you use for accessing the API is still valid. |
403 Forbidden | The request couldn't be processed due to a restriction or permission issue. | Contact the Semrush Support Team. |
404 Not Found | The request couldn't be processed because the target resource was incorrect or had been moved. | Ensure the target resource exists and is specified correctly in the request. |
409 Conflict | The request couldn't be processed due to a conflict with the current state of the resource. | Retry the request later or check the resource state–for example, when creating a project, confirm it doesn't already exist. |
429 Too Many Requests | The request couldn't be processed because there were too many requests from the user with the given access token. | Retry the request later. |
499 Client Closed Request | The request couldn't be processed because the user disconnected before receiving a response. | Check your network connection and retry the request later. |
550 Internal Server Error | The request couldn’t be processed due to a server-side error. | Retry the request later. |
551 Not Implemented | The request couldn't be processed because the specified request method isn’t supported. | To check all available methods, refer to the API version 4 reference. |
553 Service Unavailable | The request couldn't be processed due to server maintenance or overload. | Retry the request later. |
554 Gateway Timeout | The request couldn't be processed due to a timeout at the acting gateway or proxy server. | Retry the request later. |
The Listing Management API returns the standard status codes in its responses.
Except for the UpdateLocations method. If there's an error while updating one or several locations, the HTTP status code is still 200
, but the errors themselves will be described in the response. This is done so that the locations that didn't return errors get updated successfully. If it's easier, you can update locations one by one using the UpdateLocation method.
However, note that the error responses don't follow the API response format exactly as described.
These examples of error responses give you an idea of what to expect in case of a failed request. The error responses you get aim to help you find the issues in your requests and fix them.
Error response due to duplicated location IDs
{ "error": { "code": "BAD_REQUEST", "message": "Invalid state of resource.", "details": [ { "code": "LOCATIONS_ARE_NOT_UNIQUE", "message": "The locations are not unique. There are several locations with this ID: 6fb03fd6c3a943a489df2c7060218911." } ] }, "requestId": "api-flb-ec33fa653e6734980500d561b6aa3d32" }
Error response due to no location with the requested ID
{ "error": { "code": "RESOURCE_NOT_FOUND", "message": "Resource not found.", "details": [ { "code": "LOCATION_NOT_FOUND", "message": "Location is not found." } ] }, "requestId": "api-flb-fb27c729b51e658d4a4984716df00a77" }
Error response due to incorrect data format in request
{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid data provided.", "details": [ { "code": "TIMES_NOT_ALLOWED", "message": "Operation hours shouldn't be set.", "field": "holidayHours.times", "index": "0" }, { "code": "TIMES_TOO_MANY_RANGES", "message": "Only three time ranges can be set.", "field": "holidayHours.times", "index": "1" } ] }, "requestId": "api-flb-fb27c729b51e658d4a4984716df00a77" }
The Map Rank Tracker API follows the API response format.