Basic docs

Jump to About API version 4About API version 4

Semrush API version 4 includes:

Jump to Projects API overviewProjects API overview

Project API lets you get basic information about your Semrush projects, as well as perform some basic management actions (create, update, delete a project).

Jump to Listing Management API overviewListing Management API overview

Listing Management API allows you to push data from your tools into Semrush Listing Management in bulk and distribute it across directories in seconds.

Jump to Map Rank Tracker API overviewMap Rank Tracker API overview

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.

Learn more about Map Rank Tracker ›

Jump to Get access to API version 4Get access to API version 4

Semrush API version 4 is available only for the following Semrush tools and under specific conditions:

Jump to AuthorizationAuthorization

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>

Jump to AuthenticationAuthentication

The Semrush API supports two ways to grant OAuth 2.0 credentials:

  • Device Authorization Grant flow (RFC 8628)
  • Semrush Auth flow

Use one of these options to authenticate in the Semrush API. The Device Authorization Grant flow is recommended.

Jump to Device Authorization Grant flowDevice Authorization Grant flow

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.

Jump to Step 1. Request Device AuthorizationStep 1. Request Device Authorization

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)
JSON
{
  "device_code": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "user_code": "YYYYYYYYYYY",
  "verification_uri": "https://oauth.semrush.com/dag/auth/verify_code?code=ZZZZZZZZZZZ",
  "expires_in": 300,
  "interval": 5
}

Jump to Step 2. Authenticate with your Semrush accountStep 2. Authenticate with your Semrush account

This sign-in step is performed by you, as the developer, not by your end-users.

  1. Open the URL from verification_uri in a browser.
  2. Sign in with your Semrush account credentials.
  3. Approve the API access request for your application.
  4. Semrush authorizes your application and associates the approval with your device_code.

Jump to Step 3. Request Device Access TokenStep 3. Request Device Access Token

While you complete Step 2, your application polls the token endpoint at the recommended interval until:

  • You finish the authorization.
  • The device_code expires.
  • An error occurs.

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
Shell
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)
JSON
{
  "access_token": "e3wLk3PtqyVPHM7Ele61OhuZFWtKCFK4O1HQslzh",
  "token_type": "Bearer",
  "expires_in": 604800,
  "refresh_token": "YWza6vpqkW628wtMldRsQNalEu9k33Vg75PQiXGi"
}

Jump to What your application should doWhat your application should do

  • Use access_token to call the Semrush API v4 and pull data into your system.
  • Record expires_in (7 days) and refresh the bearer token before it expires.
  • Store refresh_token securely to get new access tokens (valid for 30 days, refreshed along with the bearer token).

Jump to Error responseError response

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
JSON
{
  "error": "<code>",
  "error_description": "<optional human-readable detail>"
}

For possible errors and recommended actions, refer to the Status codes table.

Jump to Semrush AuthSemrush Auth

Jump to Step 1. Get codeStep 1. Get code

  1. Contact the Semrush Tech Support to obtain your client_id and client_secret.
  2. Replace 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
  3. Log in to Semrush, if needed, and click Approve to provide access to the data. You will then be redirected to a new page with the Authorization provided title. Its URL will look similar to this: https://oauth.semrush.com/oauth2/success?code=UTyWR6YQAPUbtLIX9jWM4OifmK1ODVWDOVUt8hlk.
  4. Copy the value of the code parameter. In the earlier example, it’s UTyWR6YQAPUbtLIX9jWM4OifmK1ODVWDOVUt8hlk.

Jump to Step 2. Get access tokenStep 2. Get access token

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
Shell
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)
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
Shell
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)
JSON
{
  "access_token": "u8pPo6fo2NV70QCy7USWd3iT34CenBiT8RSuEEGn",
  "token_type": "Bearer",
  "expires_in": 604800,
  "refresh_token": "s99qrRuqbUdFRnum3R1HC9dTEJMOMs0IU1hJSi7W"
}

Jump to API response formatAPI response format

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
JSON
{"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
JSON
{
  "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"
            }
          ]
        }
      }
    ]
  }
}

Jump to Status codesStatus codes

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.

Jump to Local API error responseLocal API error response

Jump to Listing Management APIListing Management API

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
JSON
{
  "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
JSON
{
  "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
JSON
{
  "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"
}

Jump to Map Rank Tracker APIMap Rank Tracker API

The Map Rank Tracker API follows the API response format.

Last updated: January 30, 2026

Was this page helpful?