cURL
curl --request GET \
--url https://api.signa.so/v1/credits/pricing \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/credits/pricing"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/credits/pricing', 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.signa.so/v1/credits/pricing",
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.signa.so/v1/credits/pricing"
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.signa.so/v1/credits/pricing")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/credits/pricing")
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{
"object": "list",
"data": [
{
"object": "credit_price",
"id": "<string>",
"name": "<string>",
"group": "<string>",
"credits": 1,
"unit": "per_request",
"min_plan": "free",
"status": "available",
"endpoints": [
{
"method": "GET",
"path": "<string>",
"required_scope": "<string>",
"any_authenticated": true,
"required_scope_any_of": [
"<string>"
]
}
],
"required_scope": "<string>"
}
],
"has_more": false,
"pagination": {
"cursor": null
},
"schedule_version": 123,
"degraded": true,
"request_id": "<string>"
}{
"error": {
"type": "not_found",
"title": "Resource not found",
"status": 404,
"detail": "Trademark tm_xxx does not exist.",
"retryable": false,
"retry_after": null,
"instance": "/v1/trademarks/tm_xxx",
"suggestion": "Check the trademark ID. Use GET /v1/trademarks to search for marks by text.",
"errors": [
{
"field": "limit",
"code": "out_of_range",
"message": "limit must be at most 100"
}
]
},
"request_id": "req_abc123"
}Usage & Credits
Get Credit Pricing
How many credits each API action costs. No currency amounts; see the pricing page for plans and packs.
GET
/
v1
/
credits
/
pricing
cURL
curl --request GET \
--url https://api.signa.so/v1/credits/pricing \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.signa.so/v1/credits/pricing"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.signa.so/v1/credits/pricing', 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.signa.so/v1/credits/pricing",
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.signa.so/v1/credits/pricing"
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.signa.so/v1/credits/pricing")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.signa.so/v1/credits/pricing")
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{
"object": "list",
"data": [
{
"object": "credit_price",
"id": "<string>",
"name": "<string>",
"group": "<string>",
"credits": 1,
"unit": "per_request",
"min_plan": "free",
"status": "available",
"endpoints": [
{
"method": "GET",
"path": "<string>",
"required_scope": "<string>",
"any_authenticated": true,
"required_scope_any_of": [
"<string>"
]
}
],
"required_scope": "<string>"
}
],
"has_more": false,
"pagination": {
"cursor": null
},
"schedule_version": 123,
"degraded": true,
"request_id": "<string>"
}{
"error": {
"type": "not_found",
"title": "Resource not found",
"status": 404,
"detail": "Trademark tm_xxx does not exist.",
"retryable": false,
"retry_after": null,
"instance": "/v1/trademarks/tm_xxx",
"suggestion": "Check the trademark ID. Use GET /v1/trademarks to search for marks by text.",
"errors": [
{
"field": "limit",
"code": "out_of_range",
"message": "limit must be at most 100"
}
]
},
"request_id": "req_abc123"
}Returns the published credit prices as a complete list of
MCP clients can use the unbilled
credit_price items. Any valid API key can call this endpoint, and the call consumes no credits.
Each item contains id, name, group, credits, unit, min_plan, status, and endpoints (each with method and path). Units are per_request, per_page, per_record, per_item, per_screen, per_mark_per_day, or per_watch_per_day. Paths use OpenAPI parameter syntax, such as /v1/trademarks/{id}; wildcard patterns expand to concrete operations. Status is available, beta, planned, or internal. Authorized keys see internal actions with their internal status preserved. Each endpoint includes required_scope when its effective scope differs from the default trademarks:read (for example, screening:read, portfolios:manage, or events:read). Endpoints that accept alternative scopes publish required_scope: null and required_scope_any_of, listing the accepted alternatives. Endpoints that accept any authenticated key, including keys with no scopes, instead publish required_scope: null and any_authenticated: true, without required_scope_any_of. The alternative-scope case includes feedback and office-vote operations, which accept any canonical or supported legacy key scope. The row-level required_scope appears only when every published endpoint shares the same non-default scope. Meeting min_plan alone does not grant access. Admin keys also satisfy the scope requirement.
The top-level schedule_version identifies the pricing version used by billing events. Both REST and MCP always include the boolean degraded: false when the OpenAPI document builds successfully, or true when endpoints use normalized fixture paths after a document-build failure. has_more is always false and pagination.cursor is null. Prices contain no currency amounts; see plans and packs.
Beta actions show nominal prices but consume no credits during beta. Planned prices do not imply availability. Daily monitoring prices apply to the daily meter, separately from management API requests. endpoints lists the operations published in this deployment; it may be empty for daily meters and for actions whose routes are not yet enabled. Identify daily meters by unit (per_mark_per_day or per_watch_per_day), not by an empty array. If the OpenAPI document cannot be built, normalized fixture paths are returned for that request with Cache-Control: private, no-store; the next request retries the document build. Watch-management operations cost 0 credits per request; their OpenAPI price has charged_per_request: false and a separate daily price block.
Successful document builds containing only public prices use Cache-Control: public, max-age=300. Scope-restricted prices are included only for authorized keys and use private caching. Responses vary by Authorization.
import { Signa } from "@signa-so/sdk";
const signa = new Signa({ api_key: process.env.SIGNA_API_KEY });
const pricing = await signa.credits.pricing();
console.log(pricing.schedule_version, pricing.data);
get_credit_pricing tool after authentication with a key that passes the MCP transport gate: one of read, search, trademarks:read, billing:read, portfolios:manage, or admin (the legacy search:read scope is also accepted). The tool adds no further scope requirement. REST accepts any valid key, including one with no scopes.
For the actual debit on a metered call, read X-Credits-Charged; see credit headers. For your balance, use Get Credits.Authorizations
API key (sig_ prefix)
Response
Credit prices by API action
Available options:
list Show child attributes
Show child attributes
Available options:
false Show child attributes
Show child attributes
True when the OpenAPI document could not be built and endpoints use normalized fixture paths. The next request retries the build.