Client API First Calls

9 Aufrufe Markdown

The five endpoints called while connecting to the client surface.

Overview

The client API is for a customer managing their own account from an integration. It is a surface apart from the admin API: a different address and a different kind of key, with every call bounded to one customer.

This article answers the first three questions: is the surface up, what can my key do, and which values fill the address fields.

The address chain runs one way: the country code first, then the state number, then the city number. Each step wants the one before it, and any of them can come back empty.

Reference

The Health Check

get/api/v1/admin/client/ping
System/Ping no key needed

Returns that the client surface is up, along with the server time.

Response fields data — 3
pongboolWhether the surface is up.
versionstringThe API version.
timestringThe server's time. It comes in the server's own time zone.
Errors
This endpoint is open to everyone and returns no error.
Request
curl 'https://panel.example.com/api/v1/client/ping'
const res = await fetch('https://panel.example.com/api/v1/client/ping');
const { data } = await res.json();

if (! data.pong) reportOutage();
$ch = curl_init('https://panel.example.com/api/v1/client/ping');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// This is SEPARATE from the admin surface's endpoint of the same name; one can be up while the other is not.
$up = Kernel::internal('client:System/Ping')['data']['pong'] ?? false;

What the Key Is

get/api/v1/admin/client/whoami
System/Whoami no scope needed

Returns the key's identity, its permissions and the client it belongs to.

Response fields data — 6
idintThe key id.
typestringThe key kind. On this surface it is always a client key.
namestringThe name the key was given.
permissionsstring[]The scopes the key carries.
last_accessstringWhen it was last used.
owner_idintThe client the key belongs to. Every call is bounded by this client.
Errors 4
missing_token401The key was not sent or is not known.
key_revoked401The key was revoked.
audience_mismatch403An admin key was used on the client surface.
ip_not_allowed403The request came from outside the addresses allowed.
Request
curl 'https://panel.example.com/api/v1/client/whoami' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch('https://panel.example.com/api/v1/client/whoami', {
  headers: { Authorization: `Bearer ${clientKey}` },
});

if (res.status === 403) return showWrongSurface();

const { data } = await res.json();
console.log(data.owner_id, data.permissions);
$ch = curl_init('https://panel.example.com/api/v1/client/whoami');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// owner_id IS NOT PASSED on calls: the client comes from the key and writing it in the body changes nothing.
$me = Kernel::internal('client:System/Whoami', ['owner_id' => $ownerId])['data'];

The Countries

get/api/v1/admin/client/reference/countries
Reference/GetCountries no scope needed

Returns the country codes the profile and address endpoints take.

Response fields data[] — 2
codestringThe two-letter country code. The profile and address endpoints want this rather than a number.
namestringThe country name. It comes in the site's language.
Errors 3
missing_token401The key was not sent or is not known.
key_revoked401The key was revoked.
audience_mismatch403An admin key was used on the client surface.
Request
curl 'https://panel.example.com/api/v1/client/reference/countries' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch('https://panel.example.com/api/v1/client/reference/countries', {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
renderCountryPicker(data);
$ch = curl_init('https://panel.example.com/api/v1/client/reference/countries');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// The client surface speaks the COUNTRY CODE; the country NUMBER from the admin surface is not taken here.
$rows = Kernel::internal('client:Reference/GetCountries', ['owner_id' => $uid])['data'];
$codes = array_column($rows, 'code');

A Country's States

get/api/v1/admin/client/reference/countries/{code}/states
Reference/GetStates no scope needed

Returns a country's states with the numbers the address fields use.

Response fields data[] — 2
idintThe state number. It is the state field on the address endpoints and the input to the city lookup.
namestringThe state name.
Errors 4
not_found404No such country code.
missing_token401The key was not sent or is not known.
key_revoked401The key was revoked.
audience_mismatch403An admin key was used on the client surface.
Request
curl 'https://panel.example.com/api/v1/client/reference/countries/TR/states' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch(`https://panel.example.com/api/v1/client/reference/countries/${code}/states`, {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
if (! data.length) useFreeTextState();
$ch = curl_init('https://panel.example.com/api/v1/client/reference/countries/' . $code . '/states');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// AN EMPTY list is normal: with no states on that country the address field takes free text.
$states = Kernel::internal('client:Reference/GetStates', ['owner_id' => $uid, 'code' => $code])['data'];
$free   = ! $states;

A State's Cities

get/api/v1/admin/client/reference/states/{id}/cities
Reference/GetCities no scope needed

Returns a state's cities with the numbers the address fields use.

Response fields data[] — 2
idintThe city number. It is the city field on the address endpoints.
namestringThe city name.
Errors 4
not_found404No such state.
missing_token401The key was not sent or is not known.
key_revoked401The key was revoked.
audience_mismatch403An admin key was used on the client surface.
Request
curl 'https://panel.example.com/api/v1/client/reference/states/34/cities' \
  -H "Authorization: Bearer $CLIENT_KEY"
const res = await fetch(`https://panel.example.com/api/v1/client/reference/states/${stateId}/cities`, {
  headers: { Authorization: `Bearer ${clientKey}` },
});

const { data } = await res.json();
$ch = curl_init('https://panel.example.com/api/v1/client/reference/states/' . $stateId . '/cities');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $clientKey],
]);

$body = json_decode(curl_exec($ch), true);
curl_close($ch);
// A CITY IS REQUIRED on an address even when the list is empty: write free text rather than leaving it out.
$cities = Kernel::internal('client:Reference/GetCities', ['owner_id' => $uid, 'id' => $stateId])['data'];

Pitfalls

An admin key does not work on this surface

The client surface takes a client key alone, and calling with an admin key gives audience_mismatch. That code means the wrong surface rather than a missing permission, so fixing the address instead of the key wastes time.

The customer comes from the key and never from the request

Every client endpoint is bounded by the key's owner. Writing a customer number into the body changes nothing, and asking for someone else's record answers not found. Use the admin surface when you need to reach more than one customer.

The country speaks a code while the state and city speak numbers

On the client surface a country is given as a two-letter code and the country number from the admin surface is not taken. The state and city want numbers. Filling all three the same way leads to a quiet validation error.

An empty list is not an error but a sign to use free text

The state or city list can come back empty when the platform holds no data for that country or state. The address field then takes free text. A city stays required even with an empty list, and an address does not save without one.

The health check does not verify the key

The health endpoint wants no credentials, so a successful answer says nothing about your key working. Call both while wiring an integration up: the health endpoint proves the server and the key endpoint proves the credentials.

War das hilfreich?

Vielen Dank für Ihre Rückmeldung!

Brauchen Sie weitere Hilfe?

Unser Support-Team ist rund um die Uhr für Sie da, wenn Sie oben nicht fündig werden.