Get subscription and quota status
curl --request GET \
--url https://api.fetchin.io/api/v1/subscription \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.fetchin.io/api/v1/subscription"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.fetchin.io/api/v1/subscription', 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.fetchin.io/api/v1/subscription",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$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.fetchin.io/api/v1/subscription"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
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.fetchin.io/api/v1/subscription")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fetchin.io/api/v1/subscription")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"plan": "custom",
"active": true,
"status": "active",
"creditsRemaining": 684230,
"subscriptionCreditsRemaining": 184230,
"paygCreditsRemaining": 500000,
"paygExpiresAt": "2027-03-02T00:00:00.000Z",
"creditsLimit": 250000,
"creditsUsed": 65770,
"renewalDate": "2026-07-15T00:00:00.000Z",
"rpsLimit": 20,
"cancelAtPeriodEnd": false
}
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}
{
"error": "Service temporarily unable to serve this request. Please retry.",
"code": "SERVICE_UNAVAILABLE"
}
Account
Get Subscription
Check your current plan, remaining credits, RPS limit and billing status
GET
/
api
/
v1
/
subscription
Get subscription and quota status
curl --request GET \
--url https://api.fetchin.io/api/v1/subscription \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.fetchin.io/api/v1/subscription"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.fetchin.io/api/v1/subscription', 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.fetchin.io/api/v1/subscription",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$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.fetchin.io/api/v1/subscription"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
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.fetchin.io/api/v1/subscription")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fetchin.io/api/v1/subscription")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"plan": "custom",
"active": true,
"status": "active",
"creditsRemaining": 684230,
"subscriptionCreditsRemaining": 184230,
"paygCreditsRemaining": 500000,
"paygExpiresAt": "2027-03-02T00:00:00.000Z",
"creditsLimit": 250000,
"creditsUsed": 65770,
"renewalDate": "2026-07-15T00:00:00.000Z",
"rpsLimit": 20,
"cancelAtPeriodEnd": false
}
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}
{
"error": "Service temporarily unable to serve this request. Please retry.",
"code": "SERVICE_UNAVAILABLE"
}
Endpoint
GET /api/v1/subscription
Authentication
Include your API key in the request header:X-API-Key: your-api-key-here
Parameters
None. The account is identified by your API key.Response
Plan identifier, e.g.
"free" or "custom". It describes the subscription
only — an account with no plan but a live
pay-as-you-go balance still reads "free" here.Whether the subscription is in good standing.
false when the billing status is
past_due, incomplete, canceled or unpaid. This flag is about billing only —
check creditsRemaining separately to know whether you still have credits.Raw billing status. Branch your integration on this value.
free and active are
good standing; past_due / incomplete / unpaid indicate a payment problem;
canceled means the subscription has ended; trialing is a trial period.Everything you can still spend: the plan allowance left for this billing
period plus your pay-as-you-go credits.
This is the figure to gate traffic on. It can be larger than
creditsLimit,
because pay-as-you-go credits are not part of the plan allowance.The plan half of
creditsRemaining: credits left in the current billing period.
These are replaced (not topped up) at every renewal, which is why they are spent
first.The pay-as-you-go half of
creditsRemaining: credits left across every
one-time purchase you hold. Spent only once the plan allowance is exhausted,
soonest-expiring first. 0 when you hold none.When your soonest-expiring pay-as-you-go credits lapse (ISO 8601), or
null
when you hold none. Each purchase expires 12 months after its own date and is
never extended by a later one, so this is the date on which your balance can
fall without you having called anything.Credits allotted by the plan for the current billing period.
Pay-as-you-go credits are excluded, so this is not a ceiling on
creditsRemaining.Plan credits consumed so far in the current billing period —
creditsLimit
minus subscriptionCreditsRemaining. Pay-as-you-go credits spent are not
counted here, so this stays a truthful “how much of my plan have I burned this
month”.When the current billing period ends and the plan allowance is replaced
(ISO 8601), e.g.
"2026-07-15T00:00:00.000Z". Pay-as-you-go credits are
untouched by this date — they keep their own 12-month expiry.Example Request
curl -X GET "https://api.fetchin.io/api/v1/subscription" \
-H "X-API-Key: your-api-key-here"
const response = await fetch(
'https://api.fetchin.io/api/v1/subscription',
{
headers: {
'X-API-Key': 'your-api-key-here'
}
}
);
const subscription = await response.json();
console.log(subscription);
import requests
headers = {
'X-API-Key': 'your-api-key-here'
}
response = requests.get(
'https://api.fetchin.io/api/v1/subscription',
headers=headers
)
subscription = response.json()
print(subscription)
<?php
$apiKey = 'your-api-key-here';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.fetchin.io/api/v1/subscription");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . $apiKey
]);
$response = curl_exec($ch);
$subscription = json_decode($response, true);
curl_close($ch);
print_r($subscription);
?>
Example Response
{
"plan": "custom",
"active": true,
"status": "active",
"creditsRemaining": 684230,
"subscriptionCreditsRemaining": 184230,
"paygCreditsRemaining": 500000,
"paygExpiresAt": "2027-03-02T00:00:00.000Z",
"creditsLimit": 250000,
"creditsUsed": 65770,
"renewalDate": "2026-07-15T00:00:00.000Z",
"rpsLimit": 20,
"cancelAtPeriodEnd": false
}
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}
{
"error": "Service temporarily unable to serve this request. Please retry.",
"code": "SERVICE_UNAVAILABLE"
}
Errors
See Error Handling for the full list of error codes and recommended handling.401UNAUTHENTICATED/INVALID_API_KEY429RATE_LIMITED500INTERNAL_ERROR503SERVICE_UNAVAILABLE
Notes
This endpoint is free — it does not consume credits. It also returns
200 even
when you are out of credits, so you can always use it to diagnose why calls are
failing, and to tell an empty balance apart from a billing problem.It is also free of your plan’s rate limit. This endpoint has its own budget of
1 request per second per account, so polling it never costs you throughput on
the data endpoints: it returns
X-RateLimit-Cost: 0, and your plan’s per-second
budget is untouched no matter how often you call it.Two consequences. Exceeding 1 req/s here returns 429 RATE_LIMITED even when
your plan budget is completely free — that 429 is about this endpoint alone, and
its Retry-After tells you how long to wait (honor it rather than assuming a
second: this budget is metered over the same two-second window as everything else). And because the request spends none of the plan window, the
response carries no X-RateLimit-Remaining / X-RateLimit-Reset:
X-RateLimit-Limit still reports your plan’s RPS, so pace your data calls from
the headers those calls return.To decide whether you can call a data endpoint right now, check
creditsRemaining > 0 on its own. Do not require active as well: that flag
is about subscription standing, and an account paying with
pay-as-you-go credits and no plan reads status: "free" while
being perfectly able to call every endpoint — gating on active there would
stop traffic that would have succeeded. Read active separately, to warn about
a payment problem. Poll this endpoint periodically (not on every request) — the
numbers reflect our billing store and may lag real-time usage by a few seconds.Use Cases
Multi-provider arbitrage
Route traffic based on remaining credits and RPS across providers
Uninterrupted access
Detect a non-payment (
past_due) or scheduled cancellation before it blocks youUsage monitoring
Track credit consumption, renewal timing and credit expiry programmatically
Capacity planning
Confirm your effective RPS limit before scaling up request volume
Response
Current subscription and quota status
Raw billing status. Branch on this rather than the HTTP status. free and active are good standing; past_due/incomplete/unpaid indicate a payment problem; canceled means the subscription has ended.
Available options:
active, free, trialing, past_due, incomplete, unpaid, canceled Example:
"active"