> ## Documentation Index
> Fetch the complete documentation index at: https://jobo.world/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Profile schema

> Full field-level reference for the Auto Apply profile — contact, location, links, work experience, education, eligibility, preferences, self-identification, memories, and the resume file — plus every enum used by profiles, applications, and sessions.

The profile is the applicant record behind every automated application. It is **resume-first**: [importing a resume](/api-reference/auto-apply-profiles/import-a-profile-from-a-resume) fills `contact`, `location`, `links`, `work_experience`, `education`, and `memories` automatically, so the explicit sections carry only what a resume cannot state.

The same nested shape is used everywhere:

* **Resource** — returned by every profile endpoint, plus the read-only `id`, `status`, `import_error`, `resume`, `created_at`, and `updated_at` fields.
* **Request body** — [`POST /api/auto-apply/profiles`](/api-reference/auto-apply-profiles/create-a-profile) and [`PATCH /api/auto-apply/profiles/{id}`](/api-reference/auto-apply-profiles/update-a-profile) accept the resource minus the read-only fields.

<Note>
  `PATCH` is a **section-level replace**: every top-level key present in the
  body replaces that entire section; absent keys are untouched. Send `{}` (or
  `[]` for arrays) to clear a section — except `contact`, which always
  requires `first_name`, `last_name`, and `email` whenever it is present.
  `cover_letter_template` follows the same idea at field level — absent
  leaves it untouched, `""` clears it.
</Note>

All enum values are lowercase `snake_case` strings.

***

## Top level

| Field                        | Type                                        | Nullable | Description                                                                                       |
| ---------------------------- | ------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `id` *(read-only)*           | uuid                                        | No       | Stable profile identifier.                                                                        |
| `name`                       | string                                      | No       | Friendly label (e.g. `"Default"`, `"Tech applications"`). Defaults to `"Default"`; max 100 chars. |
| `status` *(read-only)*       | [profile status](#profile-status)           | No       | Lifecycle driven by the async resume import.                                                      |
| `import_error` *(read-only)* | string \| null                              | Yes      | Why the last import failed. Only set when `status` is `import_failed`.                            |
| `contact`                    | [contact](#contact)                         | No       | Contact details. Required on create.                                                              |
| `location`                   | [location](#location)                       | No       | Where the applicant lives.                                                                        |
| `links`                      | [links](#links)                             | No       | Public profile URLs.                                                                              |
| `work_experience`            | [work experience](#work-experience)\[]      | No       | Work history, most recent first. Max 50 entries.                                                  |
| `education`                  | [education](#education)\[]                  | No       | Education history. Max 20 entries.                                                                |
| `eligibility`                | [eligibility](#eligibility)                 | No       | Work authorization and sponsorship.                                                               |
| `preferences`                | [preferences](#preferences)                 | No       | Salary, start date, relocation, remote preference.                                                |
| `self_identification`        | [self-identification](#self-identification) | No       | Voluntary EEO responses — all optional.                                                           |
| `memories`                   | string\[]                                   | No       | Plain-language facts the AI uses to answer arbitrary screening questions. Max 100 × 1000 chars.   |
| `cover_letter_template`      | string \| null                              | Yes      | Optional template the AI personalizes per job. Max 10000 chars.                                   |
| `resume` *(read-only)*       | [resume](#resume-read-only) \| null         | Yes      | Stored resume file metadata, or null when no file has been uploaded.                              |
| `created_at` *(read-only)*   | date-time                                   | No       | UTC timestamp the profile was created.                                                            |
| `updated_at` *(read-only)*   | date-time                                   | No       | UTC timestamp the profile was last updated.                                                       |

### Profile status

| Value           | Meaning                                                                                        |
| --------------- | ---------------------------------------------------------------------------------------------- |
| `ready`         | Complete and usable for applications.                                                          |
| `importing`     | A resume import is building the profile — poll until it leaves this state (typically 10–30 s). |
| `import_failed` | The import failed — see `import_error`, then `PATCH` (flips back to `ready`) or re-import.     |

***

## Contact

`first_name`, `last_name`, and `email` are required when creating a profile.

| Field            | Type           | Nullable   | Description                                                                                                  |
| ---------------- | -------------- | ---------- | ------------------------------------------------------------------------------------------------------------ |
| `first_name`     | string         | Create: no | Legal first name. Max 100 chars.                                                                             |
| `last_name`      | string         | Create: no | Legal last name. Max 100 chars.                                                                              |
| `preferred_name` | string \| null | Yes        | Preferred / chosen name when it differs from the legal first name. Max 100 chars.                            |
| `email`          | string (email) | Create: no | Email address applications are submitted with.                                                               |
| `phone`          | string \| null | Yes        | Phone number, ideally international format. Max 50 chars.                                                    |
| `date_of_birth`  | date \| null   | Yes        | `YYYY-MM-DD`. Explicit input only — **never** parsed from the resume; only used when a form explicitly asks. |

## Location

All fields optional.

| Field           | Type           | Nullable | Description                                |
| --------------- | -------------- | -------- | ------------------------------------------ |
| `address_line1` | string \| null | Yes      | Street address. Max 200 chars.             |
| `city`          | string \| null | Yes      | City. Max 200 chars.                       |
| `state`         | string \| null | Yes      | State, province, or region. Max 200 chars. |
| `postal_code`   | string \| null | Yes      | Postal / ZIP code. Max 20 chars.           |
| `country`       | string \| null | Yes      | Country name. Max 200 chars.               |

## Links

Each link must be an absolute `http(s)` URL, max 500 chars.

| Field       | Type           | Nullable | Description           |
| ----------- | -------------- | -------- | --------------------- |
| `linkedin`  | string \| null | Yes      | LinkedIn profile URL. |
| `github`    | string \| null | Yes      | GitHub profile URL.   |
| `portfolio` | string \| null | Yes      | Portfolio URL.        |
| `website`   | string \| null | Yes      | Personal website URL. |

## Work experience

Array of entries, most recent first. Max 50 entries.

| Field         | Type           | Nullable | Description                                             |
| ------------- | -------------- | -------- | ------------------------------------------------------- |
| `company`     | string \| null | Yes      | Employer name.                                          |
| `title`       | string \| null | Yes      | Job title held.                                         |
| `location`    | string \| null | Yes      | Where the role was based.                               |
| `start_date`  | string \| null | Yes      | `YYYY` or `YYYY-MM`.                                    |
| `end_date`    | string \| null | Yes      | `YYYY` or `YYYY-MM`. Ignored when `is_current` is true. |
| `is_current`  | boolean        | No       | True when this is the current role.                     |
| `description` | string \| null | Yes      | What the role involved. Max 4000 chars.                 |

## Education

Array of entries. Max 20 entries.

| Field            | Type           | Nullable | Description                                                 |
| ---------------- | -------------- | -------- | ----------------------------------------------------------- |
| `school`         | string \| null | Yes      | Institution name.                                           |
| `degree`         | string \| null | Yes      | Degree obtained or in progress.                             |
| `field_of_study` | string \| null | Yes      | Major / field of study.                                     |
| `start_date`     | string \| null | Yes      | `YYYY` or `YYYY-MM`.                                        |
| `end_date`       | string \| null | Yes      | Graduation (or expected graduation) as `YYYY` or `YYYY-MM`. |
| `gpa`            | string \| null | Yes      | Free-form GPA, e.g. `"3.8"` or `"3.8/4.0"`. Max 20 chars.   |

## Eligibility

Work-authorization facts a resume cannot state.

| Field                       | Type            | Nullable | Description                                                           |
| --------------------------- | --------------- | -------- | --------------------------------------------------------------------- |
| `work_authorized_countries` | string\[]       | No       | Country names the applicant may legally work in. Max 50 entries.      |
| `requires_sponsorship`      | boolean \| null | Yes      | Whether the applicant now or in the future requires visa sponsorship. |

## Preferences

| Field                 | Type                                              | Nullable | Description                                                            |
| --------------------- | ------------------------------------------------- | -------- | ---------------------------------------------------------------------- |
| `salary_expectation`  | [salary expectation](#salary-expectation) \| null | Yes      | Expected compensation, or null to leave salary questions to the AI.    |
| `earliest_start_date` | date \| null                                      | Yes      | `YYYY-MM-DD` the applicant could start.                                |
| `willing_to_relocate` | boolean \| null                                   | Yes      | Whether the applicant is open to relocating.                           |
| `remote_preference`   | enum \| null                                      | Yes      | See [remote preference](#remote-preference).                           |
| `preferred_locations` | string\[]                                         | No       | Locations the applicant prefers (e.g. `"Austin, TX"`). Max 20 entries. |

### Salary expectation

| Field      | Type   | Nullable | Description                                  |
| ---------- | ------ | -------- | -------------------------------------------- |
| `amount`   | number | No       | Expected amount. Must be greater than 0.     |
| `currency` | string | No       | ISO 4217 currency code. Default `USD`.       |
| `period`   | enum   | No       | `year` \| `month` \| `hour`. Default `year`. |

### Remote preference

| Value      | Meaning                   |
| ---------- | ------------------------- |
| `remote`   | Fully remote preferred.   |
| `hybrid`   | Mix of remote and office. |
| `on_site`  | On-site preferred.        |
| `flexible` | No strong preference.     |

## Self-identification

Voluntary EEO responses, quarantined in their own section. **Everything here is optional** — omitted or `prefer_not_to_say` values make the applicant decline those questions on application forms.

| Field               | Type         | Nullable | Description                                      |
| ------------------- | ------------ | -------- | ------------------------------------------------ |
| `gender`            | enum \| null | Yes      | See [gender](#gender).                           |
| `ethnicity`         | enum \| null | Yes      | See [ethnicity](#ethnicity).                     |
| `veteran_status`    | enum \| null | Yes      | See [veteran status](#veteran-status). US forms. |
| `disability_status` | enum \| null | Yes      | See [self-ID answer](#self-id-answer).           |
| `lgbtq_status`      | enum \| null | Yes      | See [self-ID answer](#self-id-answer).           |

### Gender

| Value               |
| ------------------- |
| `male`              |
| `female`            |
| `non_binary`        |
| `prefer_not_to_say` |

### Ethnicity

Categories match the option sets ATS vendors use on EEO forms.

| Value                                 |
| ------------------------------------- |
| `black_or_african_american`           |
| `east_asian`                          |
| `southeast_asian`                     |
| `south_asian`                         |
| `hispanic_or_latino`                  |
| `middle_eastern`                      |
| `native_hawaiian_or_pacific_islander` |
| `american_indian_or_alaska_native`    |
| `white`                               |
| `two_or_more`                         |
| `prefer_not_to_say`                   |

### Veteran status

| Value               |
| ------------------- |
| `veteran`           |
| `not_a_veteran`     |
| `prefer_not_to_say` |

### Self-ID answer

Used by both `disability_status` and `lgbtq_status`.

| Value               |
| ------------------- |
| `yes`               |
| `no`                |
| `prefer_not_to_say` |

## Memories

A plain string array — one fact per entry, max 100 entries of 1000 characters each. The AI reads these as context when answering arbitrary screening questions ("Why do you want to work here?", "Describe your experience with X"). Resume import generates them automatically; add your own via `PATCH`.

```json theme={null}
"memories": [
  "8 years of backend engineering experience",
  "Key skills: Go, Kubernetes, PostgreSQL",
  "Led a team of 6 engineers at my last role"
]
```

## Resume (read-only)

Managed through the resume file endpoints ([upload](/api-reference/auto-apply-profiles/upload-a-resume) / [download](/api-reference/auto-apply-profiles/download-a-resume) / [delete](/api-reference/auto-apply-profiles/delete-a-resume)). `null` when no file has been uploaded.

| Field          | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `file_name`    | string    | Original file name.                           |
| `content_type` | string    | MIME type of the stored file.                 |
| `size_bytes`   | integer   | File size in bytes.                           |
| `uploaded_at`  | date-time | UTC timestamp the file was uploaded.          |
| `download_url` | string    | Host-relative URL that streams the file back. |

Upload (`PUT .../resume`) accepts PDF, DOC, DOCX, TXT, RTF, MD; import (`POST /profiles/import`) accepts PDF, DOCX, TXT, RTF, MD (legacy binary `.doc` cannot be text-extracted). Max 10 MB.

***

## Application enums

### Application status

| Value       | Terminal | Meaning                                                      |
| ----------- | :------: | ------------------------------------------------------------ |
| `running`   |    No    | Being filled and submitted — keep polling.                   |
| `submitted` |    Yes   | Successfully submitted.                                      |
| `failed`    |    Yes   | Ended without submitting — see `failure_reason` and `error`. |

### Failure reason

Set only when an application's `status` is `failed`.

| Value                               | Meaning                                                                |
| ----------------------------------- | ---------------------------------------------------------------------- |
| `expired`                           | The browser session or job posting expired mid-run.                    |
| `max_steps_reached`                 | The form had more pages/steps than the run allows.                     |
| `stalled`                           | The flow stopped making progress.                                      |
| `no_fields_found`                   | No fillable form fields were discovered on the page.                   |
| `no_answers_generated`              | The AI could not produce answers for the discovered fields.            |
| `error`                             | Any other error — see `error` for detail.                              |
| `login_required` *(reserved)*       | The ATS demanded a login or account registration.                      |
| `captcha_required` *(reserved)*     | A CAPTCHA blocked the flow.                                            |
| `redirected` *(reserved)*           | The page redirected to an external domain mid-flow.                    |
| `redirect_required` *(reserved)*    | The application continues on a different ATS the run could not follow. |
| `unsupported_provider` *(reserved)* | No supported ATS provider matched the URL.                             |

<Note>
  *Reserved* values are part of the wire contract but not yet emitted — those
  situations report `error` until dedicated detection ships. Treat the enum as
  open: handle unrecognized values like `error`.
</Note>

## Session enums

Interactive-session flow states (`form_ready`, `next_available`, `submit_ready`, `submitted`, `login_required`, `captcha_required`, `expired`, `redirected`, `redirect_required`, `error`) are documented in [Flow states](/api-reference/auto-apply/auto-apply#flow-states), and the 17 form-field types in [Field types](/api-reference/auto-apply/auto-apply#field-types).

`GET /api/auto-apply/sessions/{id}` additionally reports:

| Field   | Values                                                                  |
| ------- | ----------------------------------------------------------------------- |
| `state` | `pending` \| `running` \| `completed` \| `failed` \| `closed`           |
| `mode`  | `interactive` (sessions API) \| `automated` (behind an application run) |
