Skip to main content
These recipes show how to chain API calls for complete recruiting workflows. Each recipe includes the exact endpoints, request bodies, and expected responses.

Source candidates and add to project

Find candidates on LinkedIn and add them to a recruiting project’s pipeline.
1

Get your connected LinkedIn account

curl -X GET "https://app.leonar.app/api/v1/connected-accounts" \
  -H "Authorization: Bearer leo_your_api_key"
Response — pick an account with api_status.recruiter: "active" or api_status.sales_navigator: "active":
{
  "data": [
    {
      "id": "acc-uuid-here",
      "name": "Alice Recruiter",
      "license_type": "recruiter",
      "api_status": {
        "classic": "active",
        "sales_navigator": "inactive",
        "recruiter": "active"
      }
    }
  ]
}
2

Look up location IDs (for LinkedIn filters)

curl -X GET "https://app.leonar.app/api/v1/sourcing/linkedin/locations?q=Paris&account_id=acc-uuid-here&api_type=recruiter" \
  -H "Authorization: Bearer leo_your_api_key"
Response:
{
  "data": [
    {"id": "105015875", "title": "Paris, Ile-de-France, France"},
    {"id": "104482823", "title": "Paris Area, France"}
  ]
}
3

Search LinkedIn profiles

curl -X POST "https://app.leonar.app/api/v1/sourcing/linkedin/search" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "project-uuid",
    "account_id": "acc-uuid-here",
    "job_titles": ["Software Engineer", "Backend Developer"],
    "location_ids": {"105015875": "Paris, France"},
    "years_experience": {"min": 3, "max": 10},
    "page": 1,
    "page_size": 25
  }'
Response — profiles with already_in_project: false can be added:
{
  "data": {
    "profiles": [
      {
        "profile_id": "urn:li:member:123456",
        "first_name": "Sophie",
        "last_name": "Martin",
        "headline": "Senior Software Engineer at Doctolib",
        "current_job": {"title": "Senior Software Engineer", "company_name": "Doctolib"},
        "already_in_project": false,
        "existing_contact_id": null
      }
    ],
    "total_count": 342,
    "filtered_count": 340,
    "has_more": true,
    "next_page": 2
  }
}
4

Add selected profiles to project

Pass the full profile objects directly from the search response. Include experiences, educations, skills, summary, and picture_url to create rich contact records:
curl -X POST "https://app.leonar.app/api/v1/sourcing/add-to-project" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "project-uuid",
    "profiles": [
      {
        "profile_id": "urn:li:member:123456",
        "first_name": "Sophie",
        "last_name": "Martin",
        "headline": "Senior Software Engineer at Doctolib",
        "picture_url": "https://media.licdn.com/dms/image/example.jpg",
        "location": "Paris, Île-de-France, France",
        "linkedin_url": "https://www.linkedin.com/in/sophie-martin",
        "summary": "Experienced engineer with 8 years in full-stack development...",
        "current_job": {
          "title": "Senior Software Engineer",
          "company_name": "Doctolib"
        },
        "experiences": [
          {
            "title": "Senior Software Engineer",
            "company_name": "Doctolib",
            "start_date": "2021-03-01",
            "end_date": null,
            "description": "Leading backend team, Python/Django stack...",
            "is_current": true
          },
          {
            "title": "Software Engineer",
            "company_name": "Criteo",
            "start_date": "2018-01-01",
            "end_date": "2021-02-28",
            "description": "Built real-time bidding systems...",
            "is_current": false
          }
        ],
        "educations": [
          {
            "educational_establishment": "École Polytechnique",
            "diploma": "Master of Engineering",
            "specialization": "Computer Science",
            "start_date": "2014-09-01",
            "end_date": "2018-06-30"
          }
        ],
        "skills": ["Python", "Django", "TypeScript", "PostgreSQL"],
        "total_years_experience": 8.2
      }
    ]
  }'
The more fields you include, the richer the contact record. Fields like already_in_project and existing_contact_id from the search response are ignored — they are response-only metadata.
Response:
{
  "data": {
    "added": 1,
    "skipped": 0,
    "contact_ids": ["new-contact-uuid"],
    "skipped_profiles": [],
    "stage": {"id": "stage-uuid", "name": "Sourced", "category": "sourced"}
  }
}

Enrich a contact and find their email

1

Trigger enrichment

curl -X POST "https://app.leonar.app/api/v1/contacts/contact-uuid/enrich" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"type": "work_email"}'
Response:
{
  "data": {
    "request_id": "enrich-request-uuid",
    "type": "work_email",
    "status": "pending"
  }
}
2

Poll until completed

Enrichment is asynchronous. Poll every 5 seconds:
curl -X GET "https://app.leonar.app/api/v1/enrichment/enrich-request-uuid" \
  -H "Authorization: Bearer leo_your_api_key"
Response when completed:
{
  "data": {
    "id": "enrich-request-uuid",
    "contact_id": "contact-uuid",
    "enrichment_type": "work_email",
    "status": "completed",
    "result": {
      "email": "sophie@doctolib.com",
      "confidence": 0.95
    },
    "created_at": "2025-02-10T10:00:00Z",
    "completed_at": "2025-02-10T10:00:08Z"
  }
}
The email is automatically added to the contact record. No need to update the contact manually.

Enroll contacts in a sequence

1

List available sequences

curl -X GET "https://app.leonar.app/api/v1/sequences?status=active&limit=10" \
  -H "Authorization: Bearer leo_your_api_key"
2

Enroll contacts (simple format)

curl -X POST "https://app.leonar.app/api/v1/sequences/sequence-uuid/enroll" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_ids": [
      "contact-uuid-1",
      "contact-uuid-2",
      "contact-uuid-3"
    ]
  }'
3

Or enroll with custom variables

curl -X POST "https://app.leonar.app/api/v1/sequences/sequence-uuid/enroll" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "contact_id": "contact-uuid-1",
        "custom_variables": {
          "project_name": "Senior Frontend Engineers",
          "custom_intro": "I noticed your work on the React component library"
        }
      }
    ]
  }'
Response:
{
  "data": {
    "enrolled": 1,
    "skipped_blacklisted": 0,
    "skipped_already_enrolled": 0,
    "skipped_active_elsewhere": 0,
    "skipped_not_found": 0
  }
}

Create and manage a deal

1

Get pipeline stages

curl -X GET "https://app.leonar.app/api/v1/deal-pipelines" \
  -H "Authorization: Bearer leo_your_api_key"
2

Create a deal

curl -X POST "https://app.leonar.app/api/v1/deals" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Recruitment - 3 Senior Engineers",
    "company_id": "company-uuid",
    "pipeline_id": "pipeline-uuid",
    "amount": 45000,
    "currency": "EUR",
    "expected_close_date": "2025-03-15"
  }'
3

Link a contact to the deal

curl -X POST "https://app.leonar.app/api/v1/deals/deal-uuid/contacts" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"contact_id": "contact-uuid"}'
4

Move deal through stages

curl -X PUT "https://app.leonar.app/api/v1/deals/deal-uuid/stage" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"stage_id": "next-stage-uuid"}'
5

Close the deal

curl -X POST "https://app.leonar.app/api/v1/deals/deal-uuid/close" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "won",
    "signed_amount": 45000,
    "actual_close_date": "2025-03-10"
  }'

Search and tag contacts

1

Create a tag

curl -X POST "https://app.leonar.app/api/v1/tags" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "ai-sourced", "color": "#6366F1", "scope": "contact"}'
2

Search contacts

curl -X POST "https://app.leonar.app/api/v1/contacts/search" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "react typescript",
    "location": "Paris",
    "limit": 50
  }'
3

Tag matching contacts

For each matching contact:
curl -X POST "https://app.leonar.app/api/v1/contacts/contact-uuid/tags" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"tag_id": "tag-uuid"}'

Send a message to a contact

curl -X POST "https://app.leonar.app/api/v1/messages" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "contact-uuid",
    "channel": "email",
    "subject": "Exciting opportunity at Doctolib",
    "content": "Hi Sophie, I came across your profile..."
  }'
For LinkedIn messages, specify the channel and optionally the sender account:
curl -X POST "https://app.leonar.app/api/v1/messages" \
  -H "Authorization: Bearer leo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": "contact-uuid",
    "channel": "linkedin",
    "content": "Hi Sophie, I noticed your experience with React...",
    "sender_account_id": "account-uuid"
  }'