Reference Data
The seven lookup endpoints turning raw numbers and codes into readable labels.
Overview
The WISECP API returns raw values: a status code, a country number, a currency number. An interface has to turn those into something a person reads, and the dictionary for that sits in these seven endpoints.
The split is deliberate. The resource endpoints stay raw because a label shifts with language and time, while the dictionary stands apart because it rarely moves and can be fetched once and kept.
Three endpoints form the address chain: country, state and city. The chain runs one way, and each step wants the number from the step before.
Reference
The Currencies
Returns the currencies defined, with their numbers.
curl 'https://panel.example.com/api/v1/admin/reference/currencies' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/reference/currencies', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const byId = Object.fromEntries(data.map((c) => [c.id, c.code]));$ch = curl_init('https://panel.example.com/api/v1/admin/reference/currencies');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The numbers are NOT ISO numerics: they belong to the installation and differ between them.
$rows = Api::Reference()->GetCurrencies()['data'];
$code = array_column($rows, 'code', 'id'); // [4 => 'USD']The Countries
Returns the countries with a number, a code and a translated name.
curl 'https://panel.example.com/api/v1/admin/reference/countries?lang=en' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/reference/countries?lang=en', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const name = Object.fromEntries(data.map((c) => [c.id, c.name]));$ch = curl_init('https://panel.example.com/api/v1/admin/reference/countries?lang=en');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// Other endpoints want the COUNTRY NUMBER and not the two-letter code; build the map here.
$rows = Api::Reference()->GetCountries([], ['lang' => 'en'])['data'];
$idOf = array_column($rows, 'id', 'code'); // ['US' => 840]The States
Returns the states of one country.
curl 'https://panel.example.com/api/v1/admin/reference/states?country_id=840' \
-H "Authorization: Bearer $API_KEY"const url = new URL('https://panel.example.com/api/v1/admin/reference/states');
url.searchParams.set('country_id', countryId);
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const { data } = await res.json();
if (! data.length) allowFreeText();$ch = curl_init('https://panel.example.com/api/v1/admin/reference/states?country_id=' . $countryId);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// AN EMPTY list is normal: not every country has states, and the address field is free text there.
$states = Api::Reference()->GetStates([], ['country_id' => $countryId])['data'];
$freeText = ! $states;The Cities
Returns the cities of one state.
curl 'https://panel.example.com/api/v1/admin/reference/cities?state_id=6' \
-H "Authorization: Bearer $API_KEY"const url = new URL('https://panel.example.com/api/v1/admin/reference/cities');
url.searchParams.set('state_id', stateId);
const res = await fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
const body = await res.json();$ch = curl_init('https://panel.example.com/api/v1/admin/reference/cities?state_id=' . $stateId);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The chain runs one way: a city wants the country FIRST and then the state number.
$states = Api::Reference()->GetStates([], ['country_id' => $countryId])['data'];
$cities = Api::Reference()->GetCities([], ['state_id' => $states[0]['id']])['data'];The Languages
Returns the languages open to clients, in order.
curl 'https://panel.example.com/api/v1/admin/reference/languages' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/reference/languages', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
renderLanguagePicker(data);$ch = curl_init('https://panel.example.com/api/v1/admin/reference/languages');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The OPEN languages alone come back; the language management endpoint shows the closed ones too.
$open = Api::Reference()->GetLanguages()['data'];
$all = Api::Languages()->GetLanguages()['data'];The Billing Cycles
Pairs the billing cycle codes with the labels people read.
curl 'https://panel.example.com/api/v1/admin/reference/cycles?lang=en' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/reference/cycles?lang=en', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const label = Object.fromEntries(data.map((c) => [c.code, c.label]));$ch = curl_init('https://panel.example.com/api/v1/admin/reference/cycles?lang=en');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// The list is a LABEL source and not a gate: which cycles a product sells is a separate question.
$labels = array_column(Api::Reference()->GetCycles()['data'], 'label', 'code');
$sold = Api::Products()->GetProduct(['id' => $pid])['data']['prices'] ?? [];The Status Codes
Pairs the status codes of one kind of record with their labels.
client or product. The client set stands in when it is left out.curl 'https://panel.example.com/api/v1/admin/reference/statuses?entity=client&lang=en' \
-H "Authorization: Bearer $API_KEY"const res = await fetch('https://panel.example.com/api/v1/admin/reference/statuses?entity=client', {
headers: { Authorization: `Bearer ${apiKey}` },
});
const { data } = await res.json();
const label = Object.fromEntries(data.statuses.map((s) => [s.value, s.label]));$ch = curl_init('https://panel.example.com/api/v1/admin/reference/statuses?entity=client');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $apiKey],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);// TWO kinds exist alone: invoice, order and ticket statuses are absent here and sit in their own articles.
$out = Api::Reference()->GetStatuses([], ['entity' => 'client'])['data'];
$map = array_column($out['statuses'], 'label', 'value');Pitfalls
A currency number is the installation's own record, and one currency can carry different numbers on two installations. Resolve it from this list rather than writing it into your code. Country numbers follow the same rule: the code travels and the number does not.
Not every country has states, and the state endpoint returns an empty list for one that does not. An address form should offer free text there rather than a picker. An interface reading the empty list as a failure blocks address entry for those countries outright.
The status endpoint gives the client and product states. Invoice, order, service and ticket states are absent, and their code lists sit in their own articles. Asking for a kind that is unknown gives an error whose detail shows the list supported.
With no language parameter the labels come back in the panel's current language. That language can be hard to predict for a background job or a report builder. Always name the language when you mean to keep the result.
These lists are not meant to be fetched on every request. Country and city data hardly ever move, while currencies and languages shift when a setting does. Fetching once at start-up and holding the result is quicker and spends none of your quota.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.