SDKs and downloads
Seven languages, the same few calls in each. Free and open source under the MIT licence: use them, change them, ship them in your product.
| Language | Needs | Download |
|---|---|---|
| JavaScript / TypeScript server + web widget | Node 18+, Deno or Bun | zip · 23 KB |
| Python | Python 3.8+ | zip · 6 KB |
| C# / .NET | .NET 8, or netstandard2.0 (.NET Framework 4.6.1+) | zip · 7 KB |
| Java | Java 11+ | zip · 8 KB |
| PHP | PHP 7.4+ (uses curl when present) | zip · 6 KB |
| Go | Go 1.21+ | zip · 5 KB |
| C / C++ | C99 + libcurl; C++17 wrapper | zip · 13 KB |
| All of the above | zip · 79 KB |
Also: allowid-login.js (the web widget, also inside the JavaScript zip) · openapi.yaml (to generate a client for any other language) · LICENSE.
Every SDK passes the same ten end-to-end checks against the API before each release; each zip carries its own check program.
The calls§
| Call | Does | Billed |
|---|---|---|
scan(code) | What a QR reader read → who it is | when resolved |
create_session(purpose, attributes) | Start a website sign-in | no |
get_session(id) | The sign-in's outcome, on your server | first time authenticated |
wait_for_session(id) | Poll get_session until the person decides | as above |
session_status(id, browser_token) | Just the state, without your key | no |
usage() | This month's answers against your allowance | no |
health() | Can AllowID be reached | no |
is_allowid_code(text) | Is this an AllowID QR at all? No network. | no |
Names follow each language: createSession in JavaScript and Java,
CreateSessionAsync in C#, CreateSession(ctx, …) in Go,
allowid_create_session in C.
Configuration§
Every SDK reads the same two environment variables when you don't pass the values:
ALLOWID_API_KEY | Your key, aidk_… |
ALLOWID_BASE_URL | Default https://api.allowid.eu. Change it only when AllowID asks you to. |
Timeouts default to 10 seconds. Errors are one type per language, carrying a stable
code (see errors).
Per language§
import allowid
client = allowid.Client(api_key=None, base_url=None, timeout=10.0)
r = client.scan(text) # ScanResult(result, subject, linked, claims, repeat, usage)
r.resolved # result == "resolved"
s = client.create_session("Sign in to Example Co", ["profession"])
s.session_id, s.qr_payload, s.browser_token, s.expires_at
o = client.get_session(s.session_id) # SessionResult(state, subject, claims, usage)
o = client.wait_for_session(s.session_id, timeout=180, interval=1)
o.authenticated
client.session_status(s.session_id, s.browser_token) # "pending" | ...
client.usage() # Usage(month, used, included, hard_limit, licensed)
allowid.is_allowid_code(text)
try:
client.scan(text)
except allowid.AllowIDError as e:
e.code, e.status, e.detail, e.request_id
import { AllowID, AllowIDError, isAllowIdCode } from "@allowid/sdk";
const allowid = new AllowID({ apiKey, baseUrl, timeoutMs: 10000 }); // all optional
const r = await allowid.scan(text); // { result, subject, linked, claims, repeat, usage }
const s = await allowid.createSession({ purpose: "Sign in to Example Co", attributes: ["profession"] });
s.sessionId, s.qrPayload, s.browserToken, s.expiresAt;
const o = await allowid.getSession(s.sessionId); // { state, subject, claims, usage }
await allowid.waitForSession(s.sessionId, { timeoutMs: 180000, intervalMs: 1000 });
await allowid.sessionStatus(s.sessionId, s.browserToken);
await allowid.usage(); // { month, used, included, hard_limit, licensed }
isAllowIdCode(text);
// errors: AllowIDError { code, status, detail, requestId, usage }
// TypeScript types are included.
using AllowID;
using var allowid = new AllowIDClient(apiKey: null, baseUrl: null, httpClient: null);
ScanResult r = await allowid.ScanAsync(text); // Result, Subject, Linked, Claims, Repeat, Usage, Resolved
Session s = await allowid.CreateSessionAsync("Sign in to Example Co", new[] { "profession" });
SessionResult o = await allowid.GetSessionAsync(s.SessionId); // State, Subject, Claims, Authenticated
o = await allowid.WaitForSessionAsync(s.SessionId, TimeSpan.FromMinutes(3), TimeSpan.FromSeconds(1));
string state = await allowid.SessionStatusAsync(s.SessionId, s.BrowserToken);
Usage u = await allowid.UsageAsync();
bool looks = AllowIDClient.IsAllowIdCode(text);
// errors: AllowIDException { Code, Status, Detail, RequestId, Usage }
// Pass your own HttpClient (e.g. from IHttpClientFactory) to share connections.
import eu.allowid.sdk.AllowID;
import eu.allowid.sdk.AllowIDException;
AllowID allowid = new AllowID(); // or new AllowID(key) / new AllowID(key, baseUrl)
AllowID.ScanResult r = allowid.scan(text); // result(), resolved(), subject(), linked(), claims(), repeat()
AllowID.Session s = allowid.createSession("Sign in to Example Co", List.of("profession"));
AllowID.SessionResult o = allowid.getSession(s.sessionId()); // state(), authenticated(), subject(), claims()
o = allowid.waitForSession(s.sessionId(), Duration.ofMinutes(3), Duration.ofSeconds(1));
String state = allowid.sessionStatus(s.sessionId(), s.browserToken());
AllowID.Usage u = allowid.usage();
boolean looks = AllowID.isAllowIdCode(text);
// errors: unchecked AllowIDException { code(), status(), detail(), requestId() }
require 'vendor/autoload.php'; // or require src/Client.php and src/AllowIDException.php
$allowid = new \AllowID\Client($apiKey = null, $baseUrl = null, $timeout = 10.0);
$r = $allowid->scan($text); // ['result', 'subject', 'linked', 'claims', 'repeat', 'usage']
$s = $allowid->createSession('Sign in to Example Co', ['profession']);
// $s['session_id'], $s['qr_payload'], $s['browser_token'], $s['expires_at']
$o = $allowid->getSession($s['session_id']); // ['state', 'subject', 'claims', 'usage']
$o = $allowid->waitForSession($s['session_id'], 180, 1.0);
$state = $allowid->sessionStatus($s['session_id'], $s['browser_token']);
$u = $allowid->usage();
\AllowID\Client::isAllowIdCode($text);
// errors: \AllowID\AllowIDException { errorCode, status, detail, requestId, usage }
import allowid "github.com/allowid/allowid-go"
client := allowid.New("", "") // key, base URL; "" = environment
r, err := client.Scan(ctx, text) // *ScanResult{Result, Subject, Linked, Claims, Repeat, Usage}
r.Resolved()
s, err := client.CreateSession(ctx, "Sign in to Example Co", []string{"profession"})
// s.SessionID, s.QRPayload, s.BrowserToken, s.ExpiresAt
o, err := client.GetSession(ctx, s.SessionID) // *SessionResult{State, Subject, Claims, Usage}
o, err = client.WaitForSession(ctx, s.SessionID, time.Second) // until ctx ends
state, err := client.SessionStatus(ctx, s.SessionID, s.BrowserToken)
u, err := client.Usage(ctx)
allowid.IsCode(text)
// errors: *allowid.Error{Code, Status, Detail, RequestID, Usage}; allowid.ErrorCode(err)
#include "allowid.h" /* link with -lallowid -lcurl */
curl_global_init(CURL_GLOBAL_DEFAULT);
allowid_client *c = allowid_new(NULL, NULL); /* key, base URL; NULL = environment */
allowid_scan_result r; /* result, resolved, subject, linked, repeat, claims_json, usage */
allowid_scan(c, text, &r);
allowid_claim(&r, "email", buf, sizeof buf);
allowid_scan_result_free(&r);
const char *attrs[] = { "profession" };
allowid_session s; /* session_id, qr_payload, browser_token, expires_at */
allowid_create_session(c, "Sign in to Example Co", attrs, 1, &s);
allowid_session_result o; /* state, authenticated, subject, claims_json, usage */
allowid_get_session(c, s.session_id, &o);
char state[16];
allowid_session_status(c, s.session_id, s.browser_token, state);
allowid_usage u;
allowid_usage_get(c, &u);
allowid_is_code(text);
/* every call returns ALLOWID_OK or ALLOWID_ERROR; then
allowid_last_error(c)->code, ->status, ->detail, ->request_id */
allowid_session_free(&s); allowid_session_result_free(&o); allowid_free(c);
#include "allowid.hpp" // header-only, over the C library
allowid::Client client; // or Client(key, base_url)
auto r = client.scan(text); // result, subject, linked, repeat, claims (std::map), usage; r.resolved()
auto s = client.create_session("Sign in to Example Co", {"profession"});
auto o = client.get_session(s.session_id); // state, subject, claims; o.authenticated()
auto state = client.session_status(s.session_id, s.browser_token);
auto u = client.usage();
allowid::is_code(text);
// errors: throws allowid::Error { code, status, detail, request_id }Another language?§
The API is plain HTTPS and JSON. HTTP API has every endpoint, and openapi.yaml generates a client for most languages.