API documentation

Everything the app does is available over HTTPS + JSON, so World Space Hub, event apps, websites and your own tools can use the same contact platform. Responses always contain "ok": true|false (and "success" for older clients). Errors carry an "error" message.

Authentication — two ways

1 · API key (a server or website). Create one under Integrations; send it on every request:

X-API-Key: wsk_xxxxxxxxxxxxxxxx

An application only ever sees contacts that application saved. It can optionally keep them in its own MySQL database. Emails and phone numbers are masked unless the app was created with “return full details”.

2 · World Space ID access token (World Space Hub, or any app that already signs members in with World Space ID). Send the member’s token:

Authorization: Bearer <World Space ID access token>

The platform checks the token with World Space ID, finds (or creates) the member’s account and works on that member’s own contacts. No key to distribute, and each member’s data stays theirs. The token must include the email permission.

Base address

https://YOUR-DOMAIN/api/v1/… (same as /api/v1.php?r=…)

Limits: 240 requests per minute per application, 600 per minute per address. Over the limit you get HTTP 429.

Contacts

GET/api/v1/contacts — list. Query: q (name, company, event; exact email or phone), status (active · archived · unpublished · deleted), country_code, event, limit (≤200), offset.

curl -H "X-API-Key: $KEY" "https://YOUR-DOMAIN/api/v1/contacts?q=orbit&limit=20"

GET/api/v1/contacts/{id} — one contact.

POST/api/v1/contacts — create. Either send fields, or send a card photo and let it be read:

{ "name": "Priya Sharma", "email": "priya@orbitlabs.in", "phone": "+91 98100 12345", "company": "Orbit Labs", "designation": "Director", "country": "India", "event_name": "World Space Week 2026", "notes": "Met at the Hub stand" } { "image_base64": "<base64 JPG/PNG/WebP>", "event_name": "World Space Week 2026" }

Answer: {"status":"saved","id":"…","fields":{…}}. If the same email or phone already exists you get "status":"duplicate" and the existing id (send "allow_duplicate": true to save anyway).

POST/api/v1/contacts/{id} — update any of name, designation, company, email, phone, phone2, website, address, country, notes, event_name, event_date, event_location, approval (pending · approved · rejected).

DELETE/api/v1/contacts/{id} — moves it to the trash (kept 30 days by default). Add ?permanent=1 to delete for good.

Scan a card

POST/api/v1/scan — read a card photo, return the fields, save nothing.

curl -H "X-API-Key: $KEY" -H "Content-Type: application/json" \ -d '{"image_base64":"…"}' https://YOUR-DOMAIN/api/v1/scan → {"ok":true,"engine":"gemini","fields":{"name":"…","designation":"…","company":"…","email":"…", "phone":"+91 …","phone2":"","website":"…","address":"…","country":"India","country_code":"IN"}}

Several readers are tried in turn (Gemini, Groq, OpenRouter free models, your own model, OCR.space). If none is available you get HTTP 422 with the reasons.

Other endpoints

GET/api/v1/theme — the application’s colour, font, icon and name, so your own UI can match it.

GET/api/v1/me — who the key or token belongs to, plus plan usage.

GET/api/v1/export?format=xlsx|csv — download everything.

GET/api/v1/contracts · POST/api/v1/contracts — contract bank records (title, party, email, phone, amount, end_date).

/embed.php?key=… — an iframe-able contact list in the application’s own colours.

Public pages (no sign-in)

/c/{slug} — a member’s virtual card (QR, “Save contact”, optional exchange form). /c/{slug}?a=vcf downloads the vCard.

/event.php?code=ABC123 — an event page: participants join and see each other. JSON: /api/events.php?a=info|join|directory&code=….

POST/card.php?u={slug}&a=exchange — {name, email, phone, company, message}; lands in the card owner’s contacts.

World Space Hub example (PHP)

function wsc($conn, int $identityId, string $method, string $path, ?array $body = null): array { $token = oauth_access_token_for($conn, $identityId); // the Hub already keeps a fresh WSID token $ch = curl_init(WSC_URL . '/api/v1/' . $path); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_TIMEOUT => 40, CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, 'Content-Type: application/json'], CURLOPT_POSTFIELDS => $body === null ? null : json_encode($body)]); $r = json_decode((string)curl_exec($ch), true); curl_close($ch); return is_array($r) ? $r : ['ok' => false]; } $mine = wsc($conn, $identityId, 'GET', 'contacts?limit=50'); wsc($conn, $identityId, 'POST', 'contacts', ['image_base64' => $b64, 'event_name' => 'Hub desk']);

Status codes

400 bad input · 401 missing or wrong key / token · 402 a plan limit was reached (contacts or monthly scans) · 403 not allowed · 404 not found · 422 the card could not be read · 429 too many requests · 503 not set up (World Space ID or the application’s own database is unreachable).