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

# Quickstart

> Analyze a CV, parse a job, and match them together in your first API integration

# Quickstart

This guide walks you through the complete Fribl workflow: analyzing a CV, analyzing a job description, polling for completion, and running a match.

## Prerequisites

* A Fribl API key (contact Fribl to obtain one)
* A tool for making HTTP requests (cURL, Postman, or any HTTP client)
* Tokens in your workspace — analyzing and matching are billable

<Note>
  This walkthrough consumes a handful of tokens (analyzing one CV and one job, then one match). Check your balance first, and top up in the [Fribl Console](https://console.fribl.co) if needed:

  ```bash theme={null}
  curl https://api-service.fribl.co/api/v1/tokens/balance \
    -H "x-api-key: your-api-key-here"
  ```

  See [Tokens & Billing](/tokens) for pricing. Failed tasks are refunded automatically, so you only pay for work that completes.
</Note>

## Step 1: Analyze a CV

Submit one or more CVs for analysis. The `inputs` field accepts an array of CV text strings.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api-service.fribl.co/api/v1/cvs/analyze \
    -H "x-api-key: your-api-key-here" \
    -H "Content-Type: application/json" \
    -d '{
      "inputs": [
        "John Doe\nSenior Software Engineer\n\nExperience:\n- Senior Software Engineer at Tech Corp (2020-2023)\n  Led development of microservices architecture using Node.js and Python\n\n- Software Engineer at StartupCo (2017-2020)\n  Built REST APIs and React frontends\n\nSkills: JavaScript, Python, React, Node.js, Docker, Team Leadership, Communication\n\nEducation:\n- MSc Computer Science, University of Amsterdam (2015-2017)\n\nLanguages: English (Native), Dutch (B2)"
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api-service.fribl.co/api/v1/cvs/analyze",
      headers={
          "x-api-key": "your-api-key-here",
          "Content-Type": "application/json"
      },
      json={
          "inputs": [
              "John Doe\nSenior Software Engineer\n\nExperience:\n"
              "- Senior Software Engineer at Tech Corp (2020-2023)\n"
              "  Led development of microservices architecture\n\n"
              "Skills: JavaScript, Python, React, Node.js, Docker\n\n"
              "Education:\n- MSc Computer Science, University of Amsterdam (2015-2017)"
          ]
      }
  )

  data = response.json()["data"]
  cv_id = data["ids"][0]
  print(f"CV Task ID: {cv_id}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api-service.fribl.co/api/v1/cvs/analyze",
    {
      method: "POST",
      headers: {
        "x-api-key": "your-api-key-here",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        inputs: [
          "John Doe\nSenior Software Engineer\n\nExperience:\n- Senior Software Engineer at Tech Corp (2020-2023)\n\nSkills: JavaScript, Python, React, Node.js\n\nEducation:\n- MSc Computer Science, University of Amsterdam",
        ],
      }),
    }
  );

  const { data } = await response.json();
  const cvId = data.ids[0];
  console.log(`CV Task ID: ${cvId}`);
  ```
</CodeGroup>

The API returns task IDs and a `PENDING` status. Save the ID for status polling.

```json Response theme={null}
{
  "message": "Analyze CVs request received!",
  "data": {
    "ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"],
    "status": "PENDING"
  }
}
```

## Step 2: Poll for completion

Check the processing status until it reaches `COMPLETED`. Continue polling while the task is `PENDING`, and handle `NOT_FOUND` explicitly.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api-service.fribl.co/api/v1/cvs/status \
    -H "x-api-key: your-api-key-here" \
    -H "Content-Type: application/json" \
    -d '{
      "ids": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"]
    }'
  ```

  ```python Python theme={null}
  import time

  while True:
      status_resp = requests.post(
          "https://api-service.fribl.co/api/v1/cvs/status",
          headers={"x-api-key": "your-api-key-here", "Content-Type": "application/json"},
          json={"ids": [cv_id]}
      )
      status = status_resp.json()["data"][0]["status"]
      if status == "COMPLETED":
          print("CV analysis complete!")
          break
      elif status == "FAILED":
          print("CV analysis failed.")
          break
      elif status == "NOT_FOUND":
          print("CV task not found.")
          break
      time.sleep(3)
  ```
</CodeGroup>

```json Response theme={null}
{
  "message": "Successfully retrieved CVs status",
  "length": 1,
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "original_id": null,
      "status": "COMPLETED"
    }
  ]
}
```

## Step 3: Analyze a job description

Submit a job description for analysis using the same pattern.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api-service.fribl.co/api/v1/jobs/analyze \
    -H "x-api-key: your-api-key-here" \
    -H "Content-Type: application/json" \
    -d '{
      "inputs": [
        "Senior Software Engineer\n\nWe are looking for a Senior Software Engineer to join our team in Amsterdam.\n\nRequirements:\n- 5+ years of experience with JavaScript and Python\n- Experience with React and Node.js\n- Knowledge of Docker and CI/CD\n- Strong communication and leadership skills\n- MSc in Computer Science or related field"
      ]
    }'
  ```

  ```python Python theme={null}
  job_resp = requests.post(
      "https://api-service.fribl.co/api/v1/jobs/analyze",
      headers={"x-api-key": "your-api-key-here", "Content-Type": "application/json"},
      json={
          "inputs": [
              "Senior Software Engineer\n\nRequirements:\n"
              "- 5+ years of experience with JavaScript and Python\n"
              "- Experience with React and Node.js\n"
              "- Strong communication and leadership skills\n"
              "- MSc in Computer Science or related field"
          ]
      }
  )

  job_id = job_resp.json()["data"]["ids"][0]
  print(f"Job Task ID: {job_id}")
  ```
</CodeGroup>

<Note>
  Poll `POST /jobs/status` for the job as well, using the same pattern as Step 2. Both the CV and job must reach `COMPLETED` before matching.
</Note>

## Step 4: Match the candidate to the job

Once both reach `COMPLETED` status, run a match with your preferred scoring weights.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api-service.fribl.co/api/v1/match \
    -H "x-api-key: your-api-key-here" \
    -H "Content-Type: application/json" \
    -d '{
      "jobId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "topK": 5,
      "weights": {
        "experience": 0.25,
        "hardSkills": 0.25,
        "softSkills": 0.25,
        "education": 0.25
      },
      "candidatesIds": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"]
    }'
  ```

  ```python Python theme={null}
  match_resp = requests.post(
      "https://api-service.fribl.co/api/v1/match",
      headers={"x-api-key": "your-api-key-here", "Content-Type": "application/json"},
      json={
          "jobId": job_id,
          "topK": 5,
          "weights": {
              "experience": 0.25,
              "hardSkills": 0.25,
              "softSkills": 0.25,
              "education": 0.25
          },
          "candidatesIds": [cv_id]
      }
  )

  print(match_resp.json())
  ```
</CodeGroup>

The response includes ranked candidates with per-dimension scoring and explanations:

```json Response theme={null}
{
  "message": "Match result",
  "length": 1,
  "data": [
    [
      {
        "score_meta": {
          "education": 8.5,
          "hard_skills": 7.2,
          "soft_skills": 8.0,
          "experience": 6.5
        },
        "score_dict": {
          "education": {
            "MSc in Computer Science": {
              "score": 9,
              "criteria": "Relevant degree in required field",
              "explanation": "Candidate holds an MSc in Computer Science from the University of Amsterdam, directly matching the required qualification."
            }
          },
          "hard_skills": {
            "JavaScript": {
              "score": 8,
              "criteria": "Proficiency in JavaScript",
              "explanation": "Demonstrated extensive JavaScript experience across multiple roles including React and Node.js projects."
            },
            "Python": {
              "score": 7,
              "criteria": "Proficiency in Python",
              "explanation": "Used Python for microservices development at Tech Corp."
            }
          },
          "soft_skills": {
            "Team Leadership": {
              "score": 8,
              "criteria": "Leadership capability",
              "explanation": "Led development teams and managed cross-functional projects at Tech Corp."
            }
          },
          "experience": {
            "5+ years software development": {
              "score": 7,
              "criteria": "Years of relevant experience",
              "explanation": "Candidate has 6 years of professional software engineering experience across two roles."
            }
          }
        },
        "summary_score": 7.55,
        "final_score": 7.55,
        "person_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "job_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
      }
    ]
  ]
}
```

## File upload alternative

You can upload CV and job files directly instead of providing text:

```bash theme={null}
curl -X POST https://api-service.fribl.co/api/v1/cvs/analyze/files \
  -H "x-api-key: your-api-key-here" \
  -F "files=@/path/to/cv.pdf"
```

Supported formats: **PDF**, **DOC**, **DOCX** (max 50MB).

## Next steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore all 21 endpoints in detail with interactive examples.
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/errors">
    Understand error responses and processing statuses.
  </Card>
</CardGroup>
