API types — TypeScript

Copy the definitions below into your codebase.

Jobs: List jobs · Job by ID · Geo suggest

Jobs API

List envelope, meta.filters_applied, and job detail fields
/** Allowed field tokens for `fields`, `exclude_fields`, `extra_fields` (comma-separated). */
export type JobApiAllowedField =
  | "id" | "title" | "location" | "locations" | "application_url" | "published"
  | "has_remote" | "is_active" | "expired_at" | "language" | "employment_type"
  | "salary_min" | "salary_max" | "salary_currency" | "salary_text"
  | "experience_level" | "experience_levels" | "company" | "description";

export interface JobListPagination {
  limit: number;
  next_page: string | null;
  prev_page: string | null;
}

export type FilterApplied =
  | { key: "title"; value: string; display_label: string }
  | { key: "experience_level"; value: string; display_label: string }
  | { key: "salary"; min: number | null; max: number | null; display_label: string }
  | { key: "published_after"; value: string; display_label: string }
  | { key: "max_age"; value: number; display_label: string }
  | { key: "city_id"; kind: "city"; name: string; display_label: string; city_id: number }
  | { key: "state_id"; kind: "state"; name: string; display_label: string; state_id: number }
  | { key: "country_id"; kind: "country"; name: string; display_label: string; country_id: number }
  | { key: "location"; value: string; display_label: string }
  | { key: "remote_only"; value: true; display_label: "Remote Only" }
  | { key: "company_name"; value: string; display_label: string };

export interface JobListMeta {
  query_time_ms: number;
  filters_applied: FilterApplied[];
}

export interface JobsListResponse<TJob = Record<string, unknown>> {
  data: TJob[];
  pagination: JobListPagination;
  meta: JobListMeta;
}

/** Canonical seniority tokens (Entry / Mid / Senior / Executive). */
export type JobsApiExperienceLevelToken = "EN" | "MI" | "SE" | "EX";

export interface JobsApiCompanyTeamMember {
  name: string | null;
  title: string | null;
  linkedin_url: string | null;
  photo_url: string | null;
}

/** When `company` is non-null, `name` is always set; other fields vary by enrichment. */
export interface JobsApiCompany {
  name: string;
  description: string | null;
  logo: string | null;
  website_url: string | null;
  linkedin_url: string | null;
  twitter_url: string | null;
  github_url: string | null;
  youtube_url: string | null;
  facebook_url: string | null;
  instagram_url: string | null;
  team: JobsApiCompanyTeamMember[];
  employee_count: string | number | null;
  industry: string | null;
  headquarters: string | null;
  founded: number | null;
  specialties: string[] | null;
  location: string | null;
  registrableDomain: string | null;
}

/** One geographic row in `locations`. Optional keys differ by ingest vs normalized pipeline. */
export interface JobsApiLocation {
  kind: string | null;
  is_primary: boolean;
  city_id: number | null;
  city_name: string | null;
  state_id: number | null;
  state_name: string | null;
  state_code: string | null;
  country_id: number | null;
  country_name: string | null;
  country_code: string | null;
  lat: number | null;
  lng: number | null;
  timezone: string | null;
  raw_location?: string | null;
  region?: string | null;
  subregion?: string | null;
  is_remote?: boolean;
  confidence?: number | null;
  is_partial?: boolean;
  source_label?: string | null;
  raw_segment?: string | null;
}

/**
 * Same column allowlist as list; detail always includes `description`.
 * `experience_levels`: canonical tokens inferred from title (subset of EN/MI/SE/EX); `experience_level` is the first or null.
 */
export interface JobsApiJobDetail {
  id: number;
  title: string;
  location: string | null;
  locations: JobsApiLocation[] | null;
  application_url: string | null;
  published: string;
  description: string | null;
  has_remote: boolean;
  is_active: boolean;
  expired_at: string | null;
  language: string | null;
  employment_type: string | null;
  salary_min: number | null;
  salary_max: number | null;
  salary_currency: string | null;
  salary_text: string | null;
  experience_level: JobsApiExperienceLevelToken | null;
  experience_levels: JobsApiExperienceLevelToken[];
  company: JobsApiCompany | null;
}

export type JobDetailResponse = JobsApiJobDetail;

Allowed tokens for fields, exclude_fields, and extra_fields: id, title, location, locations, application_url, published, has_remote, is_active, expired_at, language, employment_type, salary_min, salary_max, salary_currency, salary_text, experience_level, experience_levels, company, description

Geo Suggest API

GET /geo/suggest returns a JSON array (not wrapped in data). Query: required q; optional kinds (comma-separated city, state, country, default all); optional limit (1–30, default 10).

Suggestion rows and error body
/** Result kinds returned by GET /geo/suggest */
export type GeoSuggestKind = "city" | "state" | "country";

export interface GeoSuggestCityResult {
  kind: "city";
  name: string;
  display_label: string;
  city_id: number;
}

export interface GeoSuggestStateResult {
  kind: "state";
  name: string;
  display_label: string;
  state_id: number;
}

export interface GeoSuggestCountryResult {
  kind: "country";
  name: string;
  display_label: string;
  country_id: number;
}

/** Each row includes only the id field that matches its kind. */
export type GeoSuggestResult =
  | GeoSuggestCityResult
  | GeoSuggestStateResult
  | GeoSuggestCountryResult;

/** Success: raw JSON array */
export type GeoSuggestResponse = GeoSuggestResult[];

/** Error responses (400 / 500) */
export interface GeoSuggestErrorBody {
  error: string;
}