HomeHelp › Search & discovery

5. Search & discovery

Ditto Up has its own marketplace search engine. Beneath the surface it is built on three data stores — Postgres for jobs and users, Amazon Neptune (a graph database) for terms, localities and verified credentials, and Elasticsearch / Postgres full-text for free-text matching. You don't have to think about any of that to use search; this section shows you the buttons.

In this section


5.1 The unified search bar

The search bar at the top of every page (/search) is one box that searches everything — jobs, candidates, terms, businesses, posts. It is intentionally one entry point; we filter the results by type after you submit, not before.

Query string parameter Meaning Example
q The keyword(s). Free text. ?q=plasma+welding
type Restrict to one entity type. One of job, candidate, term, business, post. &type=candidate
location City, state, zip or country. &location=Austin,+TX
radius Miles from the location. Supported on jobs and candidates. &radius=25
work_type onsite / remote / hybrid. &work_type=remote
salary_min, salary_max USD pay band. &salary_min=80000
experience entry / mid / senior / staff / principal. &experience=senior
term_type When type=term, filter to one of occupational_skill, license, certification, credential, education_degree, equipment, title. &term_type=license

Results render in search_results.html with facet chips on the left so you can refine without retyping. The page is paginated (default 20 per page).


5.2 Searching for jobs

Three entry points all hit the same engine:

  • The search bar with ?type=job or no type filter.
  • The Jobs tab on the home page.
  • The Browse all jobs link (/all_jobs).

A job result card shows:

  • Job title and company
  • Location and work type
  • Salary band (if the employer chose to show it publicly)
  • The required terms as small chips
  • Posted date and number of openings
  • A green Apply button (login required)

Clicking the card opens /job/<job_title>/<id>. From there you can see the full description, attachments, application questions, and (if you're signed in) hit Apply to land on /job/<job_title>/<id>/apply (see 2.9 The application form).

5.2.1 Filters available for job search

Filter Behaviour
Location + radius See 5.4.
Work type onsite / remote / hybrid.
Salary Min and/or max in USD. Job postings without published salary are hidden when you set a min.
Experience level Matches the employer's setting.
Required term Keep only jobs that require a specific skill/license/credential.
Posted within Last 24 h / 7 days / 30 days / any.
Visa sponsorship Yes / no.
Hiring bonus Yes / no.

You can stack as many of these as you like. Filters are visible in the URL so you can bookmark or share a search.


5.3 Searching for candidates

Pass ?type=candidate to the search bar (or use the Candidates tab on the home page or the Browse all candidates link at /all_candidates).

A candidate result card shows:

  • Profile photo and name
  • Headline
  • Location
  • A row of term chips (top 5)
  • Intro-video play button (inline)
  • Score badge of their highest-graded VBQ video, if any
  • Availability and minimum-pay (if they've shown them)

Clicking the card opens /profile/<name>/<user_id>.

5.3.1 Visibility rules

You only see candidates who:

  • Have visibility set to Public (or) you have a direct link to them, or you've messaged before, or you follow each other.
  • Have at least one term claimed.
  • Have verified their email.

Candidates whose visibility is Unlisted never appear in search; Private candidates appear only to the people they have approved.

5.3.2 Filters available for candidate search

Filter Behaviour
Skill / term Required (filters down by exact term match).
Location + radius Same engine as job radius search.
Work type preference Onsite / remote / hybrid (matches what the candidate said in /candidate-settings).
Minimum-pay floor Hide candidates whose minimum pay is above your filter ceiling.
Has VBQ video Show only candidates with at least one published VBQ.
Score band Expert / Advanced / Proficient / Developing / Emerging — matches the highest-band VBQ for the term in question.
Willing to relocate Yes / no.
Posted within Last 24 h / 7 days / 30 days.

5.3.3 Saving a candidate search

If you're an employer, click Save this search on the results page. The search is stored and you'll get email alerts whenever a new candidate matches. Manage saved searches at /recruiter/subscribe-search/ (and unsubscribe at /recruiter/unsubscribe-search/<id>/). See 3.8 Recruiter subscriptions and saved searches.


5.4 Radius & location autocomplete

Radius search ("within X miles of Y") is one of the platform's core features. It uses Ditto Up's own locality database before falling back to Google Maps.

5.4.1 The autocomplete

Anywhere you see a location field — registration, profile, job posting, search filter — it calls /place-auto-complete as you type. The endpoint runs a 3-tier dispatch:

  1. Address tier — if your input looks like a US street address (digits + text), the system queries our internal OpenAddresses dataset (currently ~37,000+ vertices for City of Mountain View, with the rest of the top-10 metros rolling out). Source label local_address.
  2. Locality tier — if it doesn't look like an address, it queries our internal GeoNames locality database (~41,500 US localities). Returns city / state / zip with coordinates. Source label local.
  3. Google fallback — if neither tier matches, it forwards to Google Maps Places API. The result is cached to Neptune as source='google_cached' so the next person who types the same query gets it served from us, not Google.

You don't pick the tier — it happens transparently. The result you click sets latitude/longitude on the form so radius search works consistently across the site.

5.4.2 Place details

After you click a suggestion, the form calls /place-details to get the structured pieces (street_number, street_name, unit, city, state, zip, country, lat, lng) for storage.

5.4.3 Radius search

To find every locality within N miles of a zip / city, the platform exposes:

GET /localities-within-miles?zip_code=94103&miles=5

This returns a list of zips sorted by Haversine distance. Job and candidate search use it under the hood when you set a radius parameter.

For employers thinking about ad spend or commute analysis, this endpoint is a fast, free way to query the database directly.


5.5 Browsing terms (skills, licenses, certifications, degrees)

Every term in the marketplace has a public detail page at:

/<term_type>/<term_name>/<term_ctid>/

Where:

  • <term_type> is occupational-skills / license / certification / credentials / education-degree / equipment / title.
  • <term_name> is the URL-slugged name (for example plasma-arc-welding).
  • <term_ctid> is the Credential Transparency Identifier (or our internal UUID if the term doesn't have a CTID yet).

The detail page (term_details.html) includes:

  • The term's definition (auto-generated by LLM and verified, if not curated).
  • The hierarchy chain (parent term → grandparent term → top-level type).
  • Marketplace insights — number of jobs that require it, number of candidates who claim it, average pay band, geographic concentration.
  • Candidates with published VBQ videos for this term, sorted by score band.
  • Open jobs that require it.
  • Sibling and related terms.

The hierarchy chain is not computed live (that was a known memory leak — see project memory). Hierarchies are pre-built and cached.

5.5.1 Verifiable credentials on the term page

Terms that come from the Credential Engine (CE) registry have an issuer field linking to the issuing organisation. Some terms are issued as W3C Verifiable Credentials — see Section 8 — Credentials & wallet.


5.6 Term tooltips

Anywhere a term appears as a chip — on a profile, in a job listing, in a search result — hovering it triggers a small tooltip served by /tooltip. The tooltip shows:

  • The term type and name.
  • Definition (truncated to ~200 chars, click to expand).
  • Marketplace stats (X jobs, Y candidates).
  • Direct link to the term detail page.

The tooltip is loaded lazily via AJAX so it doesn't slow down list rendering.


5.7 The full directories — /all_jobs and /all_candidates

If you want to browse rather than search:

Page URL Default sort
All jobs /all_jobs Newest first.
All candidates /all_candidates Newest profile first; pinned candidates float to the top.

Both pages have the same filter bar as their search counterparts and both are fully paginated. Both honour visibility rules — only public candidates appear in /all_candidates.


5.8 Type-filtered results and selecting refinements

Two extra endpoints help you stay on a single results page while changing the type filter:

URL Purpose
/type-results Same as /search but locked to a specific entity type. Used by the type tabs ("Jobs / Candidates / Terms") on the search results page.
/select-results POST handler that records facet selections and re-renders without losing the current keyword / location.

You normally won't hit these directly — they're called by the on-page facet UI.


5.9 User search

To find a specific user (by name or email) — for example to start a new conversation:

/search-users/?q=<name+or+email>

This is a thin endpoint that returns a JSON list (or HTML row list) of users matching the query. It is used by the New conversation modal in the inbox (/messages/compose/) and by the @mention autocomplete in posts and messages.

It respects visibility rules — Private users do not show up unless you already share a conversation or follow each other.


5.10 Industry, organisation and title autocomplete

Three small autocomplete endpoints power form fields across the site:

Endpoint Used in Returns
/sugg Job-title and headline fields Top 10 occupation titles starting with the typed prefix, drawn from the term graph.
/org-sugg Business-name and "previous employer" fields Top 10 organisation names from our directory + LinkedIn dictionary.
/industry-location-sugg Job posting industry / location combo Suggests industries and matching locations together so a "Healthcare in Boston" query autocompletes both halves.

These are used silently by the form code; you'll just see autocomplete dropdowns appear as you type.


Next: 6. Messaging — the platform's biggest single subsystem.

Help
How can we help?
Pick one — both reach our team.
FeedbackShare a suggestion or idea Raise a ticketReport a bug or problem