Skip to content
Wasmenia for developers

Use case

Employer at sign-up

Instead of a text field where each user writes their organisation as they like, a picker suggests from the archive as they type and stores the brand’s slug. Each organisation gets one identity in your database, with its logo ready for the team page.

Products
Search, identity data
Pulls
One per brand picked the first time
Search
Not counted

The problem, and the fix

When each user types their organisation themselves, one organisation gets many spellings: «stc», «Saudi Telecom», «STC Group». You can’t tell how many people share an employer, and you can’t show its logo.

A picker that suggests from the archive and stores slug gives each organisation one id. You know who works where, can show the logo on team pages, invoices and reports, and the logo updates when the organisation changes its identity.

Who it’s for

  • Hiring and team platforms

    The employer on profiles and team pages.

  • Government and education platforms

    The organisation a user belongs to, by id not free text.

  • Events and conferences

    Each attendee’s organisation on their badge and in the attendee list.

Try it

Type an organisation in the sign-up form and pick a suggestion, then see its card as it will appear on the team page.

Where do you work?

Search for it by the name people know.

Build it

  1. 01

    Get a key

    Open a developer account in the console and make a key. The free plan is enough to start, and the key stays on your server in an environment variable.

  2. 02

    A suggestions route of yours

    A route on your server takes what the user typed, calls search with your key, and returns slug, names and image.

  3. 03

    The field in the form

    Wait 250 ms after the last letter, cancel the previous request, and make the list work by keyboard.

  4. 04

    Store the slug

    slug on the user’s record, not the name or the logo link.

  5. 05

    Show the logo

    Read the brand’s record once and keep it; read it again when updatedAt changes.

  6. 06

    When it isn’t there

    Let the name be entered as it is, and point the user to «Request a logo» if you like.

The suggestions route

brand-picker.js

// On your server, behind your own route (say /brand-suggest): it holds the key.const base = 'https://new.wasmenia.com';/** Suggestions for what the user has typed so far. */export async function suggest(text, signal) {  const q = text.trim();  if (q.length < 2) return []; // shorter is answered empty and not counted  const url = new URL('/api/v1/search/suggest', base);  url.searchParams.set('q', q);  const res = await fetch(url, {    signal,    headers: { Authorization: `Bearer ${process.env.WASMENIA_API_KEY}` },  });  if (res.status === 429) {    // Over your plan's requests a minute: wait, then try again.    const wait = Number(res.headers.get('Retry-After') ?? 60);    throw Object.assign(new Error('rate_limited'), { wait });  }  if (!res.ok) throw new Error(`HTTP ${res.status}`);  const { items } = await res.json();  return items.map((b) => ({    slug: b.slug,          // what you store    label: b.nameAr,    secondary: b.nameEn,   // may be null    image: b.thumbUrl,     // may be null: show the name alone    verified: b.isVerified,  }));}

With the input field

// In the page: it asks your route, never Wasmenia with your key.let timer;let pending; // the request still in flight, if anyinput.addEventListener('input', () => {  clearTimeout(timer);  timer = setTimeout(async () => {    pending?.abort(); // a newer keystroke makes the older answer useless    pending = new AbortController();    try {      const url = '/brand-suggest?q=' + encodeURIComponent(input.value);      const res = await fetch(url, { signal: pending.signal });      if (res.status === 429) return pauseFor(Number(res.headers.get('Retry-After') ?? 60));      render(await res.json());    } catch (e) {      if (e.name === 'AbortError') return; // replaced by a newer request      showError();    }  }, 250);});

How many pulls it costs

Search isn’t counted. A pull is when you read the brand’s record after a pick: if you keep the record, a thousand users from 40 different organisations are 40 pulls, then one per organisation that changes.

Questions

Should I forbid free text?

No. Not every organisation is in the archive. Suggest first, and accept the name as typed when the user doesn’t find theirs.

Why not call from the browser?

The key is a secret, and browsers on other sites can’t send it. A small route on your server holds it.

Products it uses

Available

Identity data

The name in both languages, other names, colours and their source, fonts and guidelines.

Available

Search

Up to 8 suggestions by name as people type, in Arabic or English.

Build it step by step

The request, the wait between letters, cancelling the previous request, and 429.