List of states
curl --request GET \
--url https://api.cloro.dev/v1/states \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.cloro.dev/v1/states"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.cloro.dev/v1/states', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/states",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/states"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cloro.dev/v1/states")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/states")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"code": "AL",
"name": "Alabama"
},
{
"code": "AK",
"name": "Alaska"
},
{
"code": "AZ",
"name": "Arizona"
},
{
"code": "CA",
"name": "California"
},
{
"code": "DC",
"name": "District of Columbia"
},
{
"code": "NY",
"name": "New York"
},
{
"code": "TX",
"name": "Texas"
}
]{
"success": false,
"error": "Request validation failed",
"details": [
{
"field": "prompt",
"message": "Prompt cannot be empty"
}
]
}{
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": "Maximum retries exceeded"
}Utilities
List of states
Returns a list of US states supported for state-level geo-targeting. Only US is currently supported — other country values return an empty array.
GET
/
v1
/
states
List of states
curl --request GET \
--url https://api.cloro.dev/v1/states \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.cloro.dev/v1/states"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.cloro.dev/v1/states', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/states",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/states"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.cloro.dev/v1/states")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/states")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"code": "AL",
"name": "Alabama"
},
{
"code": "AK",
"name": "Alaska"
},
{
"code": "AZ",
"name": "Arizona"
},
{
"code": "CA",
"name": "California"
},
{
"code": "DC",
"name": "District of Columbia"
},
{
"code": "NY",
"name": "New York"
},
{
"code": "TX",
"name": "Texas"
}
]{
"success": false,
"error": "Request validation failed",
"details": [
{
"field": "prompt",
"message": "Prompt cannot be empty"
}
]
}{
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": "Maximum retries exceeded"
}Returns the states available for state-level geo-targeting, which is supported for the US only. State targeting works on ChatGPT, Copilot, Perplexity, Gemini, and Grok; Google and AI Mode use the
Can I use
It depends on the operation:
location / uule parameters for sub-country precision instead.
Adding the state parameter to a monitor request adds +2 credits on top of the base cost and any other add-ons.
Request parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
country | string | Yes | ISO 3166-1 alpha-2 country code. Only "US" returns results. | US |
Example usage
curl -X GET "https://api.cloro.dev/v1/states?country=US" \
-H "Authorization: Bearer YOUR_API_KEY"
import requests
response = requests.get(
"https://api.cloro.dev/v1/states",
params={"country": "US"},
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
states = response.json()
# [{"code": "AL", "name": "Alabama"}, {"code": "AK", "name": "Alaska"}, ...]
const response = await fetch('https://api.cloro.dev/v1/states?country=US', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const states = await response.json();
// [{"code": "AL", "name": "Alabama"}, {"code": "AK", "name": "Alaska"}, ...]
Response
[
{ "code": "AL", "name": "Alabama" },
{ "code": "AK", "name": "Alaska" },
{ "code": "AZ", "name": "Arizona" },
{ "code": "CA", "name": "California" },
{ "code": "DC", "name": "District of Columbia" },
{ "code": "NY", "name": "New York" },
{ "code": "TX", "name": "Texas" }
]
Response schema
| Field | Type | Description |
|---|---|---|
code | string | USPS two-letter state code (e.g., "CA") |
name | string | Full state name (e.g., "California") |
Using states in monitor requests
Pass thecode value as state alongside country: "US":
curl -X POST "https://api.cloro.dev/v1/monitor/chatgpt" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "best Italian restaurants near me",
"country": "US",
"state": "CA"
}'
import requests
response = requests.post(
"https://api.cloro.dev/v1/monitor/chatgpt",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"prompt": "best Italian restaurants near me",
"country": "US",
"state": "CA"
}
)
Common questions
Can I use state with a non-US country?
It depends on the operation:
GET /v1/states?country=GB(or any non-US country) — returns an empty array, no error.statefield in a monitor request (e.g.,POST /v1/monitor/chatgpt) with a non-UScountry— returns a 400 validation error. Thestatefield is only accepted whencountryis"US".
How does state targeting work?
cloro routes your request through a proxy located in that US state, which changes the local results, regional content, and location-specific information the AI provider returns.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
ISO 3166-1 alpha-2 country code. Only "US" returns results.
Required string length:
2Pattern:
^[A-Z]{2}$Response
List of supported states
Example:
[
{ "code": "AL", "name": "Alabama" },
{ "code": "AK", "name": "Alaska" },
{ "code": "AZ", "name": "Arizona" },
{ "code": "CA", "name": "California" },
{
"code": "DC",
"name": "District of Columbia"
},
{ "code": "NY", "name": "New York" },
{ "code": "TX", "name": "Texas" }
]
Was this page helpful?
⌘I