API
Your own scripts and services read your availability, projects and absences with a private key.
Authentication
Create a key in the API section of your account. The API comes with a plan, so you need an active trial or subscription. A new key replaces the old one, and you see it only once.
Send the key as a bearer token:
Authorization: Bearer YOUR_KEY
The key only reads the data of its own account.
GET /v1/availability
Returns your availability for the next 26 weeks, with the projects and absences behind it.
curl https://api.freelance.link/v1/availability \
-H "Authorization: Bearer YOUR_KEY"
Example response
The weeks array always has 26 entries. It is shortened here.
{
"profile_url": "https://freelance.link/jane",
"waitlist_url": "https://freelance.link/jane/waitlist/new",
"status": "Booked until week 51. Available from week 9.",
"state": "booked",
"date_precision": "week",
"free_from": "2027-03-01",
"days_per_week_min": 5,
"days_per_week_max": 5,
"free_windows": [
{ "from": "2027-03-01", "until": "2027-05-02", "weeks": 9, "days_per_week_min": 5, "days_per_week_max": 5 }
],
"horizon_until": "2027-05-02",
"confirmed_on": "2026-11-02",
"links": ["https://jane.example"],
"verified_domain": "jane.example",
"available_from": "2027-03-01",
"profile_visible": true,
"weeks": [
{ "starts_on": "2026-12-14", "state": "booked", "days_per_week": 0 },
{ "starts_on": "2026-12-21", "state": "unavailable", "days_per_week": 0 },
{ "starts_on": "2027-01-04", "state": "tentative", "days_per_week": 0 },
{ "starts_on": "2027-03-01", "state": "free", "days_per_week": 5 }
],
"projects": [
{ "id": 812, "name": "ACME relaunch", "starts_on": "2026-10-05", "ends_on": "2026-12-18", "days_per_week": 5, "commitment": "booked" },
{ "id": 815, "name": "Shop migration", "starts_on": "2027-01-04", "ends_on": "2027-02-26", "days_per_week": 3, "commitment": "tentative" }
],
"absences": [
{ "id": 54, "starts_on": "2026-12-21", "ends_on": "2027-01-01" }
]
}
Fields
Dates are ISO 8601 strings (YYYY-MM-DD). Days per week are whole numbers from 0 to 5.
| Field | Meaning |
|---|---|
profile_url |
String or null. Your public profile. Null without a username. |
waitlist_url |
String or null. Where people join your waitlist. Null without a username. |
status |
String. The status sentence from your profile, in your account language. |
state |
String. Your state today: free, tentative, booked or unavailable (absent). |
date_precision |
String. How precisely your profile names dates: week, month or none. |
free_from |
Date or null. The start of the week or month in which you are free next. Null with precision none or if you have no free week ahead. |
days_per_week_min, days_per_week_max |
Integer or null. Free days per week in the next free weeks in a row. Null if you have no free week in the next 26 weeks. |
free_windows |
Array or null. Free periods in the next 26 weeks, widened to whole weeks or months. Each has from, until, weeks (length), days_per_week_min and days_per_week_max. Null with precision none. |
horizon_until |
Date. The last day of the 26 weeks. |
confirmed_on |
Date. When you last changed or confirmed your availability. |
links |
Array of strings. The links on your profile. |
verified_domain |
String or null. Your domain, if your email address and one of your links share it. |
available_from |
Date or null. The exact first free day, after projects and absences, whatever the precision. Null if you have no free week ahead. |
profile_visible |
Boolean. Whether your profile is public. |
weeks |
Array of 26 weeks, starting with this one. Each has starts_on (Monday), state (as above) and days_per_week (free days, 0 unless the week is free). |
projects |
Array of projects that haven’t ended yet, by start date. Each has id, name (string or null), starts_on, ends_on, days_per_week (1 to 5) and commitment (booked or tentative). |
absences |
Array of absences that haven’t ended yet, by start date. Each has id, starts_on and ends_on. |
Errors
Errors come as JSON with a code and a message:
{ "code": "invalid_key", "message": "Missing or invalid API key." }
| Status | Code and meaning |
|---|---|
| 401 | invalid_key: the key is missing or wrong. |
| 403 | plan_required: your account has no active trial or subscription. |
| 429 | rate_limited: more than 60 requests in a minute. Try again a minute later. |
Language
The API speaks your account language. It sets the status sentence. All other values stay the same in every language.
Without a key
Anyone can read the public part of a visible profile at freelance.link/<username>.json, without a key. It has the same fields as the API up to verified_domain, without the exact first free day, the weeks, projects and absences.
To read and change your availability from your own agent, such as Claude or ChatGPT, connect it to the MCP server instead.