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

# Resume Parsing

> Parse candidate data from DOC/DOCX resumes

## Workflow fields

<Tip>
  We recommend creating this workflow in the [anyformat platform](https://app.anyformat.ai) where you can test with sample resumes and iterate on field descriptions. Copy the workflow ID to use with the API.
</Tip>

| Field                 | Type    | Description                                                      |
| --------------------- | ------- | ---------------------------------------------------------------- |
| `candidate_name`      | string  | Full name of the candidate                                       |
| `email`               | string  | Email address                                                    |
| `phone`               | string  | Phone number                                                     |
| `skills`              | list    | Technical and professional skills                                |
| `years_of_experience` | integer | Total years of professional experience                           |
| `education`           | object  | Educational background (institution / degree / graduation\_date) |
| `work_history`        | object  | Previous employment (company / title / start\_date / end\_date)  |

## End-to-end

<Tabs>
  <Tab title="curl" icon="terminal">
    ```bash theme={null}
    # 1. Create the workflow
    curl -X POST 'https://api.anyformat.ai/v2/workflows/' \
      -H 'Content-Type: application/json' \
      -H "Authorization: Bearer $ANYFORMAT_API_KEY" \
      -d '{
        "name": "Resume Parser",
        "description": "Extract candidate details from resumes",
        "nodes": [
          {"id": "parse_1", "type": "parse"},
          {
            "id": "extract_1",
            "type": "extract",
            "extraction_schema": {
              "fields": [
                {"name": "candidate_name",      "description": "Full name of the candidate",                                              "data_type": "string"},
                {"name": "email",               "description": "Email address",                                                           "data_type": "string"},
                {"name": "phone",               "description": "Phone number including country code if present",                          "data_type": "string"},
                {"name": "skills",              "description": "List of technical skills, programming languages, tools, and competencies", "data_type": "list"},
                {"name": "years_of_experience", "description": "Total years of professional work experience",                             "data_type": "integer"},
                {
                  "name": "education",
                  "description": "Educational qualifications and degrees",
                  "data_type": "object",
                  "nested_fields": [
                    {"name": "institution",     "description": "University or school name",                  "data_type": "string"},
                    {"name": "degree",          "description": "Degree obtained (e.g. BSc CS, MBA)",         "data_type": "string"},
                    {"name": "graduation_date", "description": "Date of graduation",                          "data_type": "date"}
                  ]
                },
                {
                  "name": "work_history",
                  "description": "Previous jobs and roles, most recent first",
                  "data_type": "object",
                  "nested_fields": [
                    {"name": "company",    "description": "Company name",                                  "data_type": "string"},
                    {"name": "title",      "description": "Job title",                                     "data_type": "string"},
                    {"name": "start_date", "description": "Start date of employment",                       "data_type": "date"},
                    {"name": "end_date",   "description": "End date of employment, or empty if current",    "data_type": "date"}
                  ]
                }
              ]
            }
          }
        ],
        "edges": [{"source": "parse_1", "target": "extract_1"}]
      }'

    # 2. Run a resume
    curl -X POST 'https://api.anyformat.ai/v2/workflows/WORKFLOW_ID/run/' \
      -H "Authorization: Bearer $ANYFORMAT_API_KEY" \
      -F 'file=@resume.docx'

    # 3. Poll for results (412 → keep polling; 200 → done)
    curl -H "Authorization: Bearer $ANYFORMAT_API_KEY" \
      'https://api.anyformat.ai/v2/workflows/WORKFLOW_ID/files/COLLECTION_ID/results/'
    ```
  </Tab>

  <Tab title="TypeScript" icon="js" iconType="brands">
    ```typescript theme={null}
    import { Anyformat, Schema } from "@anyformat/sdk";

    const af = new Anyformat({ apiKey: process.env.ANYFORMAT_API_KEY! });
    const file: File = /* a File with .name set, e.g. new File([bytes], "resume.docx") */;

    const workflow = await af
      .workflow("Resume Parser", "Extract candidate details from resumes")
      .parse()
      .extract([
        Schema.string("candidate_name",      "Full name of the candidate"),
        Schema.string("email",               "Email address"),
        Schema.string("phone",               "Phone number including country code if present"),
        Schema.string("skills",              "List of technical skills, programming languages, tools, and competencies"),
        Schema.integer("years_of_experience","Total years of professional work experience"),
        Schema.object("education", "Educational qualifications and degrees", [
          Schema.string("institution",     "University or school name"),
          Schema.string("degree",          "Degree obtained (e.g. BSc CS, MBA)"),
          Schema.date("graduation_date",   "Date of graduation"),
        ]),
        Schema.object("work_history", "Previous jobs and roles, most recent first", [
          Schema.string("company",    "Company name"),
          Schema.string("title",      "Job title"),
          Schema.date("start_date",   "Start date of employment"),
          Schema.date("end_date",     "End date of employment, or empty if current"),
        ]),
      ])
      .create();

    const run = await workflow.run(file);
    const result = await run.wait();

    console.log(result.field("candidate_name")?.value);
    console.log(result.field("email")?.value);
    console.log(result.field("years_of_experience")?.value);
    // Nested rows: result.extractions[0].fields.work_history
    ```
  </Tab>

  <Tab title="Python" icon="python" iconType="brands">
    ```python theme={null}
    import os
    from anyformat.sdk import Client
    from anyformat.workflow import Schema

    client = Client(api_key=os.environ["ANYFORMAT_API_KEY"])

    workflow = (
        client.workflow("Resume Parser")
        .parse()
        .extract([
            Schema.string("candidate_name",      "Full name of the candidate"),
            Schema.string("email",               "Email address"),
            Schema.string("phone",               "Phone number including country code if present"),
            Schema.string("skills",              "List of technical skills, programming languages, tools, and competencies"),
            Schema.integer("years_of_experience","Total years of professional work experience"),
            Schema.object("education", "Educational qualifications and degrees", fields=[
                Schema.string("institution",     "University or school name"),
                Schema.string("degree",          "Degree obtained (e.g. BSc CS, MBA)"),
                Schema.date("graduation_date",   "Date of graduation"),
            ]),
            Schema.object("work_history", "Previous jobs and roles, most recent first", fields=[
                Schema.string("company",    "Company name"),
                Schema.string("title",      "Job title"),
                Schema.date("start_date",   "Start date of employment"),
                Schema.date("end_date",     "End date of employment, or empty if current"),
            ]),
        ])
        .create()
    )

    result = workflow.run("resume.docx").wait()

    print(result.fields["candidate_name"].value)
    print(result.fields["email"].value)
    print(result.fields["years_of_experience"].value)
    # Nested rows: result.raw["extractions"][0]["fields"]["work_history"]
    ```
  </Tab>
</Tabs>

## Tips

<Note>
  DOCX resumes typically yield better results than scanned PDFs since the text is natively accessible.
</Note>

* Describe `end_date` as "empty if current role" so processing returns `null` for current positions.
* `years_of_experience` as `integer` lets you filter directly without parsing.

## Next steps

<CardGroup cols={2}>
  <Card title="Run workflow" icon="play" href="/api-reference/workflows/run">
    All input methods: file upload and text
  </Card>

  <Card title="Field types" icon="diagram-project" href="/concepts/field-types">
    Lists, objects, and other field shapes
  </Card>
</CardGroup>
