Skip to main content
You build the screens in your own product. This page fixes what those screens contain, where things go, and which texts come from Vort. It is what certification tests against. RFC 2119 keywords apply.
Wireframes are left-to-right for readability. In Hebrew (he) every screen MUST be mirrored right-to-left, including list order within rows, icons with a direction, and progress bars (which fill from the right).

What you may customize, and what you may not

Your product’s own chrome around the Vort screens (navigation, page header, help menu) is yours. The rules above apply to everything inside it that shows Vort data. Constraints on colors: text and icons MUST meet WCAG 2.1 AA contrast (4.5:1 for body text, 3:1 for large text and icons) on their background; info, warning and blocking MUST be distinguishable from each other and from normal content; meaning MUST never be carried by color alone (every state also has an icon or a label). General layout rules:
  • One number per fact. Do not add percentages, scores or counts Vort did not send.
  • No nested cards: a candidate card does not contain other cards; notices inside a card are inline rows, not boxes within the box.
  • Nothing Vort sent is hidden behind a click by default, with the exception explicitly allowed for long evidence text below.

Fixed labels

Your own UI chrome (button captions such as “Find candidates”, “Reveal”, “Save”) is yours to word, provided it does not contradict Vort’s content.

Screen 1: Connect Vort

Where: your customer-admin settings. Purpose: redeem the activation code.
Wireframe
  • The input is posted to your server, which calls POST /activations/redeem. The browser never talks to Vort.
  • On 404 code_not_found, 409 code_already_redeemed, 410 code_expired, show the API message under the input. On 409 external_id_taken, tell the admin this workspace is already connected and to contact Vort.
  • Reconnect: on 401 invalid_org_token from any later call, show this screen again in the disconnected state with a note that the connection must be renewed.
The org token MUST NOT be displayed, logged to the browser console, stored in browser storage, or returned to the browser in any response. The connected state shows organization_name only.

Screen 2: Job and requirements editor

Where: your job page. Purpose: send the job and the recruiter’s requirements, surface the must cap before submit, and show Vort’s validation.
Wireframe
  • Each requirement has its text and a must/nice control, in the order the recruiter arranged them. That order is the index Vort uses everywhere.
  • Must cap before submit. A counter Must: n / 3 is always visible above the list. When 3 musts are set, the control that would make a 4th must is disabled and shows the fixed must-cap label. The request MUST NOT be sent with more than 3 musts; if it is (for example, an old client), the 422 too_many_musts message is shown like any other rejection.
  • Job fields (title, description_text, location_text) come from your job record. On 422 job_rejected, show each rejected[] message next to its field.
  • Rejected (422 requirements_rejected): nothing was started. Show every rejected[] item’s message, and its suggestion when not null, directly under the requirement at index, verbatim, in the error color with the ✖ icon. Keep the recruiter’s text in the field so it can be edited, and keep “Find candidates” available for the resubmit.
  • Warnings (in a 422 body or in the 202 response): show each under its requirement with the ⓘ icon in the warning color. They MUST NOT block submission. After a 202, the warnings stay visible on the results screen’s requirement list for that run.
  • If the recruiter submits no requirements, omit requirements; Vort derives them from the job description.
  • “Find candidates” calls your server, which calls POST /runs. On a timeout or 5xx, do not auto-retry (it would start a second run); show an error with a manual retry.

Screen 3: Run results

Where: opens right after 202 with the run_id. Purpose: progress, notices, candidates.
Wireframe
Empty list:
Wireframe

Run ID

The run_id MUST be visible on this screen without interaction (in the header or a footer line of the results area), labeled with the fixed “Run ID” label, selectable, with a copy action. You MAY show it in a smaller, secondary style. It MUST also appear in any error message you show for this run.

Progress

  • While status is running, show progress.confirmed / progress.target as a number pair and a determinate bar. A spinner alone is not enough. You MAY add progress.screened as secondary text.
  • Update on every poll (recommended every 5 s while the screen is open). New candidates are appended in API order; do not reorder cards the recruiter is looking at, except to insert new ones where the API places them.
  • On completed, replace “Searching…” with the final count (confirmed / target). If confirmed < target, the notices explain why; do not add your own explanation.
  • On failed, stop the progress indicator and show the notices (typically in empty_state or above_list) and the run_id.
  • The recruiter MAY leave the screen while a run is running. The run continues on Vort’s side; returning to the screen resumes polling.

Notices

Generic-rendering rule and catalogue: Notices. Per-severity visual rules:
  • Every notice shows title and body verbatim. If body is longer than 3 lines you MAY clamp it with a “more” control; title and the first line stay visible.
  • Unknown code, unknown slot, unknown severity: see the fallbacks in the generic-rendering rule.
  • Report rendered codes in notices_shown (see Screen 6).

Screen 4: Candidate card

Wireframe
  • Header: name, then title · company · location (omit null parts, no placeholders). The verdict badge uses the fixed label and the verdict color for strong / good / weak.
  • One row per entry in requirements[], in index order: met icon (✓ true, ✗ false, ? null), fixed kind label, requirement text, and evidence under it, verbatim. When evidence is null, show the fixed met label (“Unknown” / “Not met” / “Met”) instead of an empty line.
  • Evidence longer than 2 lines MAY be clamped with a “more” control. The met icon, kind and requirement text are never hidden.
  • The card MUST NOT show a score, percentage or ranking number Vort did not send.
  • Keep the API’s candidate order.

Screen 5: Reveal contact

Wireframe
The price shown before the click MUST be the candidate’s reveal_price_credits from the most recent GET /runs/{run_id} response. It MUST NOT be hard-coded, configured on your side, or reused from another run.
  • After the reveal, show email and phone (a null value is shown as “not found”, never as a blank), and credits_charged and wallet_balance_after exactly as returned.
  • contact_state: revealed cards show the contact block instead of the reveal button (fetch the details again via reveal: a repeat reveal is not charged).
  • On 402 insufficient_credits, show the API message, balance and required. Do not offer a retry button that repeats the same call.

Screen 6: Decision capture

Every decision below MUST be sent to POST /runs/{run_id}/decisions, with the acting recruiter, at the time it is made (or in a batch within minutes).
Wireframe
  • The reject menu MUST list exactly the seven fixed reasons with their fixed labels, plus an optional free-text note. Picking a reason is optional for the recruiter; if none is picked, send reject_reason: null and the note.
  • Shortlisted, contacted, interviewing, hired are sent as those decision values. If your ATS pipeline has its own stages, map the stages that mean these five outcomes to them; every such transition for a Vort candidate MUST be sent, including transitions made later in your pipeline screens, not only on this screen.
  • Notes travel in note on the decision they accompany, so offer the note field in the same step as the decision (as in the reject menu above). A note typed later is welcome: send the same decision again with the note and a NEW occurred_at, and Vort keeps it as a new entry in the candidate’s history. Only an exact retry (same occurred_at) is deduplicated.
  • Undo in your UI (for example “un-reject”) does not delete the earlier decision at Vort in v1. Send the new decision (for example shortlisted); both are kept, with their occurred_at, so Vort reads the latest as the current state.
notices_shown: include the codes of all notices rendered for this run (known and unknown). Send them with the first decision batch, and whenever a newly rendered code appears. If the recruiter leaves without deciding anything, send decisions: [] with notices_shown.