API Documentation

The seospark.io API allows you to access data available in seospark.io through a programmable HTTP interface.

Authorization

All API requests must include your API key in an Authorization HTTP header as follows:

Authorization: Bearer SEOSPARK_API_KEY

If you are subscribed to a version of seospark.io that includes API access, you can find your API key in the account page of your dashboard.

Rate limits

Access to the API is rate limited. Rate limits are calculated on an account basis, meaning all requests made with your API keys are counted towards the same limit. Different endpoints of the API have individual rate limits based on their intended usage.

API responses include the X-Ratelimit-Limit, X-Ratelimit-Remaining and X-Ratelimit-Reset headers which you can use to make sure you are not triggering rate limits by accident.

The respective rate limits for each endpoint are included in the documentation below.

Credits

Your account is charged a certain amount of credits for using different endpoints. Credits are included in your subscription. For larger projects, you can purchase on-demand credits. Please note that an active subscription is needed to access the API.

The respective cost for each endpoint is included in the documentation below.

You can use the GET /account endpoint to get the current number of credits available on your account.

API model

Data formats

The API communicates via HTTP and uses JSON payloads.

  • number fields are represented as actual numbers in request / response JSON payloads. Numbers are never encoded as strings ("4.6").
  • boolean fields are represented as actual booleans in request / response JSON payloads. Booleans are never encoded as strings ("true", "false") or number values (0, 1).
  • Date fields are represented as simplified extended ISO 8601 formatted strings, in terms of UTC+0. Example: "2022-02-25T10:30:15.000Z".

Request format

  • GET requests accept parameters as URL parameters.
  • POST requests accept parameters in a JSON-encoded request body (Content-Type: application/json).

Response format

  • Response payloads have a content type of application/json; charset=utf-8. The Content-Type HTTP header is set accordingly.
  • Response payloads are in JSON format with keys following the snake_case naming convention.
  • Response payloads have one of the following two base structures, depending on whether the request failed or succeeded:

    Success

    //  HTTP StatusCode: 200
    {
        "status": "success"
    
        /**
         * The amount of credits deducted from your account's balance for this operation.
         */
        "cost": number
    
        /**
         * The response data for the given endpoint.
         * If the endpoint does not return data and simply acknowledges
         * the successful processing of the request, this field is set to `null`.
         */
        "data": {...} | [...] | null
    }
    

    Error

    {
        "status": "error"
    
        /**
         * A distinct error code indicating the type of error that occurred.
         */
        "error_code": string
    
        /**
         * If applicable, a human readable, detailed explanation of why the error occurred.
         */
        "message"?: string | string[]
    }
    

    The HTTP StatusCode is also set to represent the error (see error_code details in the endpoint documentation). However, since error_code values generally describe the issue that occurred more accurately, we advise you to rely on them to handle error responses.

Payload compression

The API requires gzip compression of response payloads. After profiling the API extensively, we have decided to make adoption of gzip compression mandatory for all API users. Since we're potentially querying data for thousands of keyword combinations, data for some queries can get quite big (multiple MBs uncompressed). In oder to ensure the service is running smoothly in the future, we need to keep data throughput at a sane level.

To enable gzip compression, add the Accept-Encoding: gzip header to your requests and use a gzip compatible client to run the query. Here is a list of tools and open source HTTP clients that support gzip by default:

If you're using one of these to access the API, you shouldn't have to worry about enabling compression at all.

Common error codes

  • bad_request :400
    The request payload or one of the payload fields was either badly formatted or is missing.

    If request payload fields were missing or badly formatted, the message response field will contain detailed information for each payload field. Additionally, invalid_fields will contain a list of invalid payload field names causing the error to occur.

    Example json // HTTP StatusCode: 400 { "status": "error", "error_code": "bad_request", "message": ["country_code must be one of the following values: us, de, {...}"], "invalid_fields": ["country_code"] }
  • unauthorized :401
    The Authorization header is missing or the API Key you have provided is invalid.

  • forbidden :403
    The api key provided is not entitled to access the requested resource.

  • insufficient_credits :403
    Your account credit balance is too low for that operation. Either upgrade your plan or purchase on-demand credits to continue.

  • not_found :404
    The requested resource does not exist.

  • gzip_required :406
    The Accept-Encoding HTTP header is missing the gzip option. More info.

  • rate_limit_exceeded :429
    You have made too many requests to this endpoint and the rate limit is in effect. The Retry-After HTTP header indicates how many seconds to wait before making a follow-up request.

  • internal_server_error :500
    The request could not be processed for an unknown reason. It is probably best to indicate to your users to retry the request after a few minutes.

Quick start

  1. If you are subscribed to a version of seospark.io that includes API access, find your API key in the account page of the dashboard.
  2. Try the request below to fetch information about your account's access status.
curl -X GET \
     -H "Authorization: Bearer YOUR_API_KEY" \
     --compressed \
     https://api.seospark.io/v1/account
  1. You should see a response describing your account's current access and credit status similar to the example here.

Endpoints

GET /account

https://api.seospark.io/v1/account

This endpoint is used to fetch information about your account's current access and credit status.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

Usage of this endpoint is free of charge.

Request parameters

This endpoint has no parameters.

Response data

{
    /**
     * The amount of credits on your account.
     *
     * Subscription credits are replenished on the 1st of every month while you have an active subscription.
     */
    "credits": number
},
Example json // HTTP StatusCode: 200 { "status": "success", "data": { "credits": 14500 } }

POST /keywords/suggest

https://api.seospark.io/v1/keywords/suggest

This endpoint is used to fetch suggestions for a seed keyword.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

20 credits for every 50 keywords queried (default page size: 50).

Examples – You query a single page of data with default page size (50 keywords):
20 credits – You query 10 pages of data with default page size (50 keywords):
20 credits * 10 = 200 credits – You query a single page of data with page size 500:
20 credits * roundup(500/50) = 200 credits

Request parameters

{
    /**
     * The country for which to find keywords.
     */
    "country_code": string

    /**
     * The language for which to find keywords.
     */
    "language_code": string

    /**
     * The seed keywords for which to find suggests.
     *
     * <= 80 characters.
     */
    "keyword": string

    /**
     * For a given seed keyword, we may find more than a few hundres pages of data.
     * Use this parameter to query additional pages.
     *
     * optional
     *
     * default: 0
     */
    "page_index"?: number

    /**
     * How many keywords to return per page.
     *
     * >= 50
     * <= 500
     *
     * optional
     *
     * default: 50
     */
    "page_size"?: number

    /**
     * Filters to apply to the search for keywords.
     *
     * A maximum of 7 filters can be applied to a given search.
     *
     * optional
     *
     * default: {}
     */
    "filter"?: {
        "search_volume"?: {
            "min"?: number
            "max"?: number
        }
        "difficulty"?: {
            "min"?: number
            "max"?: number
        }
        "competition"?: {
            "min"?: number
            "max"?: number
        }
        "cpc":?: {
            "min"?: number
            "max"?: number
        }
        "search_intent"?: ('informational' | 'navigational' | 'commercial' | 'transactional')[]
    }

    /**
     * A sort definition to query keywords in a given order.
     * Sort order is defined with the following format: `{field},{direction}`
     *
     * optional
     *
     * default: 'searchVolume,desc'
     */
    "sort"?: `${'keyword' | 'difficulty' | 'searchVolume' | 'cpc' | 'competition'},${'asc' | 'desc'}`
}

Refer to the locations endpoint for a list of valid values for country_code and language_code.

Response data

{
    "keywords": {
        /**
         * Pagination information
         */
        "pagination": {
            "page_index": number
            "page_size": number
            "pages_count": number
        }

        /**
         * The filter used for this query or `null`, if no filter was given.
         */
        "filter": Filter | null

        /**
         * The sort definition used for this query.
         */
        "sort": Sort

        "meta": {
            /**
             * The total number of keywords found for this query.
             */
            "total_count": number
        }

        "items": {
            /**
             * The keyword found in the query.
             */
            "keyword": string

            /**
             * Metrics for the keyword.
             *
             * - May be null if no metrics could be found.
             */
            "metrics": null | {

                /**
                 * When the metrics for this keyword where last updated in our database.
                 */
                "updated_at": Date

                /**
                 * The average search volume over the last 12 months.
                 */
                "average_search_volume": number | null

                /**
                 * The historical search volume for the last 12 months.
                 */
                "search_volume_history": {
                    "period_start": Date
                    "value": number
                }[]

                /**
                 * The relative amount of competition associated with the given keyword.
                 * The value is based on Google Ads data and can be between 0 and 1 (inclusive).
                 */
                "competition": number | null

                /**
                 * The average cost per click (in USD) historically paid for the keyword.
                 */
                "cpc": number | null

                /**
                 * The average number of daily impressions of the advertisement
                 * if a bid is set to 999.
                 */
                "daily_impressions_average": number | null

                /**
                 * Keyword difficulty.
                 *
                 * - Indicates how hard it is to rank for this keyword organically.
                 * - 0-100, higher values mean harder to rank.
                 */
                "keyword_difficulty": number | null

                /**
                 * Types of search results (items) found in SERP.
                 *
                 * As the Google SERP evolves, more types might be added.
                 *
                 * Example values:
                 * - organic
                 * - paid
                 * - featured_snippet
                 * - local_pack
                 * - people_also_ask
                 * - video
                 * - related_searches
                 * - knowledge_graph
                 */
                "serp_item_types": string[]

                /**
                 * Number of search results for the keyword.
                 */
                "serp_results_count": number | null

                /**
                 * The search intents for this keyword. Sorted by most likely, desc.
                 *
                 * Search intent is the term used to describe the purpose of an online search.
                 * Itโ€™s the reason why a user types a particular query into a search engine.
                 *
                 * Detected search intents include:
                 * Informational โ€“ seeking information or answers to certain questions.
                 * Navigational โ€“ looking for a specific site or page.
                 * Commercial โ€“ do research before making a purchase decision.
                 * Transactional โ€“ completing a specific action, usually a purchase.
                 */
                "search_intents": ('informational' | 'navigational' | 'commercial' | 'transactional')[] | null
            }
        }
    }
}
Example json // HTTP StatusCode: 200 { "status": "success", "cost": 20, "data": { "keywords": { "pagination": { "page_index": 0, "page_size": 50, "pages_count": 510 }, "filter": null, "sort": "searchVolume,desc", "meta": { "total_count": 25490 }, "items": [ { "keyword": "baum", "metrics": { "updated_at": "2025-02-16T12:08:05.617Z", "competition": 0.03, "cpc": 0.3, "daily_impressions_average": 14, "keyword_difficulty": 38, "serp_results_count": 328000000, "serp_item_types": [ "organic", "people_also_ask", "video", "related_searches", "knowledge_graph" ], "search_intents": ["informational"], "average_search_volume": 110000, "search_volume_history": [ { "period_start": "2025-01-01T00:00:00.000Z", "value": 60500 }, { "period_start": "2024-12-01T00:00:00.000Z", "value": 60500 }, { "period_start": "2024-11-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-10-01T00:00:00.000Z", "value": 135000 }, { "period_start": "2024-09-01T00:00:00.000Z", "value": 110000 }, { "period_start": "2024-08-01T00:00:00.000Z", "value": 201000 }, { "period_start": "2024-07-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-06-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-05-01T00:00:00.000Z", "value": 110000 }, { "period_start": "2024-04-01T00:00:00.000Z", "value": 135000 }, { "period_start": "2024-03-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-02-01T00:00:00.000Z", "value": 60500 } ] } }, ... ] } }

Error codes

  • invalid_filter :400
    The filter contains more than 7 rules.

POST /keywords/metrics

https://api.seospark.io/v1/keywords/metrics

This endpoint is used to fetch metrics for your list of keywords. You can fetch metrics for up to 500 keywords with one request.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

20 credits + 1 credit for every 5 keywords.

Examples – You send a list of 3 keywords to this endpoint:
20 credits + (roundup(3 / 5) * 1 credit) = 21 credits – You send a list of 300 keywords to this endpoint:
20 credits + (roundup(300 / 5) * 1 credit) = 80 credits

Request parameters

{
    /**
     * The country for which to fetch metrics.
     */
    "country_code": string

    /**
     * The language for which to fetch metrics.
     */
    "language_code": string

    /**
     * The keywords for which to fetch metrics.
     *
     * - Max array size: 500.
     * - Each keyword must be less than 80 characters.
     * - Keywords will be lowercased, duplicates will be removed.
     */
    "keywords": string[]
}

Refer to the locations endpoint for a list of valid values for country_code and language_code.

Response data

{
    "keywords": {
        /**
         * The keyword you supplied.
         */
        "keyword": string

        /**
         * Metrics for the keyword.
         *
         * - May be null if no metrics could be found.
         */
        "metrics": null | {

            /**
             * When the metrics for this keyword where last updated in our database.
             */
            "updated_at": Date

            /**
             * The average search volume over the last 12 months.
             */
            "average_search_volume": number | null

            /**
             * The historical search volume for the last 12 months.
             */
            "search_volume_history": {
                "period_start": Date
                "value": number
            }[]

            /**
             * The relative amount of competition associated with the given keyword.
             * The value is based on Google Ads data and can be between 0 and 1 (inclusive).
             */
            "competition": number | null

            /**
             * The average cost per click (in USD) historically paid for the keyword.
             */
            "cpc": number | null

            /**
             * The average number of daily impressions of the advertisement
             * if a bid is set to 999.
             */
            "daily_impressions_average": number | null

            /**
             * Keyword difficulty.
             *
             * - Indicates how hard it is to rank for this keyword organically.
             * - 0-100, higher values mean harder to rank.
             */
            "keyword_difficulty": number | null

            /**
             * Types of search results (items) found in SERP.
             *
             * As the Google SERP evolves, more types might be added.
             *
             * Example values:
             * - organic
             * - paid
             * - featured_snippet
             * - local_pack
             * - people_also_ask
             * - video
             * - related_searches
             * - knowledge_graph
             */
            "serp_item_types": string[]

            /**
             * Number of search results for the keyword.
             */
            "serp_results_count": number | null

            /**
             * The search intents for this keyword. Sorted by most likely, desc.
             *
             * Search intent is the term used to describe the purpose of an online search.
             * Itโ€™s the reason why a user types a particular query into a search engine.
             *
             * Detected search intents include:
             * Informational โ€“ seeking information or answers to certain questions.
             * Navigational โ€“ looking for a specific site or page.
             * Commercial โ€“ do research before making a purchase decision.
             * Transactional โ€“ completing a specific action, usually a purchase.
             */
            "search_intents": ('informational' | 'navigational' | 'commercial' | 'transactional')[] | null
        }
    }[]
}
Example json // HTTP StatusCode: 200 { "status": "success", "cost": 10, "data": { "keywords": [ { "keyword": "baum", "metrics": { "updated_at": "2024-09-28T10:05:33.137Z", "competition": 0.02, "cpc": 0.34, "daily_impressions_average": 14, "keyword_difficulty": 24, "serp_results_count": 368000000, "serp_item_types": ["organic", "people_also_ask", "video", "related_searches", "knowledge_graph"], "search_intents": ["informational"], "average_search_volume": 110000, "search_volume_history": [ { "period_start": "2024-08-01T00:00:00.000Z", "value": 201000 }, { "period_start": "2024-07-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-06-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-05-01T00:00:00.000Z", "value": 110000 }, { "period_start": "2024-04-01T00:00:00.000Z", "value": 135000 }, { "period_start": "2024-03-01T00:00:00.000Z", "value": 90500 }, { "period_start": "2024-02-01T00:00:00.000Z", "value": 60500 }, { "period_start": "2024-01-01T00:00:00.000Z", "value": 74000 }, { "period_start": "2023-12-01T00:00:00.000Z", "value": 60500 }, { "period_start": "2023-11-01T00:00:00.000Z", "value": 135000 }, { "period_start": "2023-10-01T00:00:00.000Z", "value": 110000 }, { "period_start": "2023-09-01T00:00:00.000Z", "value": 110000 } ] } } ] } }

POST /clustering

https://api.seospark.io/v1/clustering

This endpoint is used to create and schedule clustering jobs.

Since clustering tens of thousands of keywords can take upwards of two minutes, the clustering endpoint group uses a 'schedule and poll' mechanism in order to avoid long running requests and reduce API load. You schedule clustering jobs with this endpoint and use the clusters, keywords and also-asked endpoints to poll the job's status and data.

Rate limit

This endpoint is rate limited to 10 requests / minute.

Cost

10 credits for every 10 keywords.

Examples – You create a clustering with 64 keywords:
(roundup(64 / 10) * 10 credits) = 70 credits – You create a clustering with 4500 keywords:
(roundup(4500 / 10) * 10 credits) = 4500 credits

Request parameters

{
    /**
     * The country for which to find fetch SERPs and metrics.
     */
    "country_code": string

    /**
     * The language for which to find fetch SERPs and metrics.
     */
    "language_code": string

    /**
     * The keywords to cluster.
     *
     * - Min array size: 10.
     * - Max array size: 100000.
     * - Each keyword must be less than 80 characters.
     * - Keywords will be lowercased.
     * - Be careful not to send duplicates in this array! Deduplication will happen internally, but only after your account has been charged for the number of keywords present in this array.
     */
    "keywords": string[]

    /**
     * The device for which to fetch serps when we calculate the keyword overlap.
     *
     * optional
     *
     * default: 'mobile'
     */
    "serp_device"?: 'mobile' | 'desktop'

    /**
     * The SERP overlap threshold.
     * The clustering algorithm will group keywords that have a SERP overlap >= this threshold.
     *
     * optional
     *
     * default: 0.3
     */
    "serp_overlap_threshold"?: 0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 | 1
}

Refer to the locations endpoint for a list of valid values for country_code and language_code.

Response data

{
    /**
     * The id of the clustering job.
     * Use this id to query the clusters, keywords and also-asked endpoints.
     */
    "id": string

    "status": {
        "value": "processing"

        /**
         * An estimate for when the job will have finished processing.
         */
        "eta": Date
    }
}
Example json // HTTP StatusCode: 200 { "status": "success", "cost": 400, "data": { "id": "67b1b0680bbe25ee376a05b2", "status": { "value": "processing", "eta": "2024-02-01T10:30:45.000Z" } } }

GET /clustering/:id/clusters

https://api.seospark.io/v1/clustering/:id/clusters

This endpoint is used to retrieve clusters found in a clustering job.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

Usage of this endpoint is free of charge.

Path parameters

  • id: The id of the clustering job. Returned from a call to the create endpoint.

Request parameters

{
    /**
     * Use this parameter to query additional pages.
     *
     * optional
     *
     * default: 0
     */
    "page_index"?: number

    /**
     * How many items to return per page.
     *
     * >= 50
     * <= 500
     *
     * optional
     *
     * default: 50
     */
    "page_size"?: number
}

Response data

{
    /**
     * Information about the clustering job and its status.
     */
    "job": {
        "id": string
        "created_at": Date
        "parameters": {
            "country": string
            "language": string
            "keywords": {
                "total_count": number
                "excerpt": string[]
            }
        }
        "status":
        | {
            "value": "processing"
            "eta": Date
          }
        | {
            "value": "failed"
          }
        | {
            "value": "succeeded"
            "clusters_count": number
          }
    }

    /**
     * Clusters data.
     *
     * -    Might be `null` if the job is still processing or failed.
     * -    Might be `"loading"` if the job is currently recalculating metrics data for the clusters.
     *      Metrics data is calculated initially and cached for 3 days. If this endpoint is invoked for a job
     *      that has no cached metrics data, we need to recalculate it.
     *      Recalculation takes no longer than a few seconds.
     */
    "clusters":
        | {
            "pagination": {
                "page_index": number
                "page_size": number
                "pages_count": number
            }
            "meta": {
                /**
                 * Total number of clusters.
                 */
                "total_count": number

                /**
                 * Cumulative search volume of all keywords across all clusters.
                 */
                "total_search_volume": number
            }
            "items": {
                /**
                 * The id of the cluster.
                 * Can be used to query keywords and also asked items for this cluster.
                 */
                "id": string

                /**
                 * The name of the cluster is derived from the keyword with the highest sv in it.
                 */
                "name": string

                /**
                 * Cumulative search volume of all keywords in the cluster.
                 */
                "search_volume": number

                /**
                 * Search intent distrubtion of keywords in the cluster.
                 */
                "search_intents": {
                    "informational": number
                    "navigational": number
                    "commercial": number
                    "transactional": number
                }

                /**
                 * The average difficulty across all keywors in the cluster.
                 * If no keyword in the cluster has the difficulty metric available, this field is `null`.
                 */
                "difficulty_average": number | null

                "keywords_count": number
                "keywords_excerpt": null | {
                    "id": string
                    "keyword": string
                    "search_volume" number
                    "difficulty": number | null
                    "search_intent": "informational" | "navigational" | "commercial" | "transactional" | null
                    "overlap": number | null
                }[]

                "also_asked_count": number
                "also_asked_excerpt": null | {
                    "id": string
                    "keyword": string
                    "search_volume": number
                    "question": string
                    "answer": null | {
                        "title": string | null
                        "description": string | null
                        "url": string | null
                    }
                }[]
            }
          }
        | null
        | "loading"
}

GET /clustering/:id/keywords

https://api.seospark.io/v1/clustering/:id/keywords

This endpoint is used to retrieve keywords found in a clustering job, sorted by search volume.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

Usage of this endpoint is free of charge.

Path parameters

  • id: The id of the clustering job. Returned from a call to the create endpoint.

Request parameters

{
    /**
     * Use this parameter to query additional pages.
     *
     * optional
     *
     * default: 0
     */
    "page_index"?: number

    /**
     * How many items to return per page.
     *
     * >= 50
     * <= 500
     *
     * optional
     *
     * default: 50
     */
    "page_size"?: number

    /**
     * Id of a cluster for which to retrieve keywords.
     * If not set, this endpoint returns keywords across all clusters, sorted by search volume.
     */
    "cluster_id"?: string
}

Response data

{
    /**
     * Information about the clustering job and its status.
     */
    "job": {
        "id": string
        "created_at": Date
        "parameters": {
            "country": string
            "language": string
            "keywords": {
                "total_count": number
                "excerpt": string[]
            }
        }
        "status":
        | {
            "value": "processing"
            "eta": Date
          }
        | {
            "value": "failed"
          }
        | {
            "value": "succeeded"
            "clusters_count": number
          }
    }

    /**
     * Keywords data.
     *
     * -    Might be `null` if the job is still processing or failed.
     * -    Might be `"loading"` if the job is currently recalculating metrics data for the clusters.
     *      Metrics data is calculated initially and cached for 3 days. If this endpoint is invoked for a job
     *      that has no cached metrics data, we need to recalculate it.
     *      Recalculation takes no longer than a few seconds.
     */
    "keywords":
        | {
            "pagination": {
                "page_index": number
                "page_size": number
                "pages_count": number
            }
            "meta": {
                /**
                 * Total number of keywords.
                 */
                "total_count": number

                /**
                 * Cumulative search volume of all queried keywords.
                 */
                "total_search_volume": number
            }
            "items": {
                /**
                 * The id of the keyword node in the clustering.
                 */
                "id": string

                /**
                 * The keyword.
                 */
                "keyword": string

                /**
                 * Average search volume over the last 12 months.
                 */
                "search_volume" number

                "difficulty": number | null
                "search_intent": "informational" | "navigational" | "commercial" | "transactional" | null

                /**
                 * The overlap value for this keyword and the main keyword of the cluster.
                 */
                "overlap": number | null
            }
          }
        | null
        | "loading"
}

GET /clustering/:id/also-asked

https://api.seospark.io/v1/clustering/:id/also-asked

This endpoint is used to retrieve also asked items found in a clustering job, sorted by search volume of the associated keyword.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

Usage of this endpoint is free of charge.

Path parameters

  • id: The id of the clustering job. Returned from a call to the create endpoint.

Request parameters

{
    /**
     * Use this parameter to query additional pages.
     *
     * optional
     *
     * default: 0
     */
    "page_index"?: number

    /**
     * How many items to return per page.
     *
     * >= 50
     * <= 500
     *
     * optional
     *
     * default: 50
     */
    "page_size"?: number

    /**
     * Id of a cluster for which to retrieve items.
     * If not set, this endpoint returns items across all clusters, sorted by search volume.
     */
    "cluster_id"?: string
}

Response data

{
    /**
     * Information about the clustering job and its status.
     */
    "job": {
        "id": string
        "created_at": Date
        "parameters": {
            "country": string
            "language": string
            "keywords": {
                "total_count": number
                "excerpt": string[]
            }
        }
        "status":
        | {
            "value": "processing"
            "eta": Date
          }
        | {
            "value": "failed"
          }
        | {
            "value": "succeeded"
            "clusters_count": number
          }
    }

    /**
     * Also asked data.
     *
     * -    Might be `null` if the job is still processing or failed.
     * -    Might be `"loading"` if the job is currently recalculating metrics data for the clusters.
     *      Metrics data is calculated initially and cached for 3 days. If this endpoint is invoked for a job
     *      that has no cached metrics data, we need to recalculate it.
     *      Recalculation takes no longer than a few seconds.
     */
    "also_asked":
        | {
            "pagination": {
                "page_index": number
                "page_size": number
                "pages_count": number
            }
            "meta": {
                /**
                 * Total number of items.
                 */
                "total_count": number

                /**
                 * Cumulative search volume of all keywords associated with queried items.
                 */
                "total_search_volume": number
            }
            "items": {
                /**
                 * The id of the also asked node in the clustering.
                 */
                "id": string

                /**
                 * The keyword for which this also asked item was found in the SERP.
                 */
                "keyword": string

                /**
                 * Average search volume over the last 12 months of the associated keyword.
                 */
                "search_volume" number

                /**
                 * The question of this also asked item
                 */
                "question": string

                /**
                 * The answer associated with the question found by expanding the
                 * also asked item in the SERP.
                 */
                "answer": null | {
                    "url": string | null
                    "title": string | null
                    "description": string | null
                }
            }
          }
        | null
        | "loading"
}

GET /locations

https://api.seospark.io/v1/locations

This endpoint serves as a lookup for valid values for the country_code and associated language_code parameters for the endpoints above.

Rate limit

This endpoint is rate limited to 100 requests / minute.

Cost

Usage of this endpoint is free of charge.

Request parameters

This endpoint has no parameters.

Response data

[
    {
        "label": "Algeria",
        "country_code": "dz",
        "language_codes": [
            {
                "label": "French",
                "language_code": "fr"
            },
            {
                "label": "Arabic",
                "language_code": "ar"
            }
        ]
    },
    {
        "label": "Angola",
        "country_code": "ao",
        "language_codes": [
            {
                "label": "Portuguese",
                "language_code": "pt"
            }
        ]
    },
    {
        "label": "Azerbaijan",
        "country_code": "az",
        "language_codes": [
            {
                "label": "Azeri",
                "language_code": "az"
            }
        ]
    },
    {
        "label": "Argentina",
        "country_code": "ar",
        "language_codes": [
            {
                "label": "Spanish",
                "language_code": "es"
            }
        ]
    },
    {
        "label": "Australia",
        "country_code": "au",
        "language_codes": [
            {
                "label": "English",
                "language_code": "en"
            }
        ]
    },
    ...
]
Table of contents