# API documentation
This API places a backlink for a page you send us.
First, create an API key. Then create a task. You can create a task in two ways.
1. The first way is to **ID** a specific donor. **Get ID** from **List donors**. The list includes the domain rating of each donor, so you know the rating of that donor.
2. The second way is to create the task without a donor ID. Then our team decides where to place the link. Send us a **domain rating range**. We will find a forum and place a link.
Create the task with **Create task**. The response includes the **task id**.
Then:
1. You can call Task status with **task id** and check the status yourself,
2. or set up a webhook so we send the **task status** to you.
To create a task we need:
1. keyword
2. Target URL for backlink
3. the domain rating range.
```
Create task
keyword
target URL
domain rating range
|
+---------------------+---------------------+
| |
v v
Get Donors List Set Dr from Dr to
Send donor ID Set Language
Set Dr from Dr to our team picks best value
Set Language the forum
| |
+---------------------+---------------------+
|
v
response: task id
|
+---------------------+---------------------+
| |
v v
call Task status webhook sends
with the task id the task status
```
Base URL: `https://api.forumbacklinks.org`
## Methods
- [GET List donors](#list-donors)
- [POST Create task](#create-task)
- [GET Get task status](#get-task-status)
- [DELETE Delete task](#delete-task)
<a id="list-donors"></a>
## List donors
`GET` `200` `/v1/donors`
Enabled forums only. Each row has its language and our domain rating.
Auth: Bearer API key created after sign-in
### Headers
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| Authorization | string | yes | Bearer API key created in the account after sign-in |
### Query params
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| language | string | no | Optional language filter. Allowed: DUTCH, ENGLISH, FRENCH, GERMAN, ITALIAN, JAPANESE, POLISH, PORTUGUESE, SPANISH, VIETNAMESE |
| drFrom | number | no | Optional DR lower bound. Send it together with drTo. Must be at least 10 |
| drTo | number | no | Optional DR upper bound |
No request body.
### Response
`object`
### Response fields
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| donors | array | yes | Enabled donors |
| donors[].id | number | yes | Pass this value as donorId on POST /v1/tasks |
| donors[].domain | string | yes | Donor site domain |
| donors[].language | string | yes | Donor language, such as ENGLISH or GERMAN |
| donors[].domainRating | number | no | Our domain rating from ahrefs_domain_rating. Omitted when that field is empty |
### Request
```
curl -sS "https://api.forumbacklinks.org/v1/donors?language=ENGLISH&drFrom=10&drTo=50" \
-H "Authorization: Bearer your_key"
```
### Response example
```
{
"donors": [
{
"id": 776,
"domain": "180degreehealth.com",
"language": "ENGLISH",
"domainRating": 42
},
{
"id": 793,
"domain": "360mate.com",
"language": "ENGLISH",
"domainRating": 12
}
]
}
```
Only forums with available = 1 are returned. Disabled forums are omitted. language is the stored language code, such as ENGLISH or GERMAN. domainRating is our ahrefs_domain_rating. It is omitted when that field is empty. A DR filter uses that same field and drops forums that do not have it.
<a id="create-task"></a>
## Create a link task
`POST` `201` `/v1/tasks`
Create a placement for a page URL. Send a forum id, or a forum domain-rating range.
Auth: Bearer API key created after sign-in
### Headers
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| Authorization | string | yes | Bearer API key created in the account after sign-in |
| Content-Type | string | yes | application/json |
### Body
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| keyword | string | yes | Anchor text. 1 to 100 characters |
| url | string | yes | http or https page that should receive the placement |
| donorId | number | no | Optional id from GET /v1/donors. The donor must be enabled. When sent, that donor stays pinned |
| drFrom | number | no | Optional DR lower bound. Send it together with drTo. Must be at least 10. A lower rating can have no donor |
| drTo | number | no | Optional DR upper bound. Must be greater than or equal to drFrom and no higher than the highest enabled donor rating |
### Response
`object`
### Response fields
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| status | string | yes | Link task created successfully |
| taskId | number | yes | Id to keep and pass to GET /v1/tasks/{taskId}/status |
### Request
```
curl -sS -X POST https://api.forumbacklinks.org/v1/tasks \
-H "Authorization: Bearer your_key" \
-H "Content-Type: application/json" \
-d '{"keyword":"apply for immortality","url":"https://www.macleod.com/immortality-application","drFrom":30,"drTo":50}'
```
### Response example
```
{
"status": "Link task created successfully",
"taskId": 20505
}
```
Send donorId to pin one enabled forum, or drFrom and drTo together to ask for a rating range. Omit both to leave the forum empty for a later manual pick. A donorId that is missing or not enabled returns 400. When both a forum and a range are sent, our ahrefs_domain_rating must fall inside the range. drFrom must be at least 10. A lower rating can have no donor. drTo cannot be above the highest enabled donor rating. Each POST creates a new task. Read it with GET /v1/tasks/{taskId}/status.
<a id="get-task-status"></a>
## Get task status
`GET` `200` `/v1/tasks/{taskId}/status`
Read one task by the task id from create.
Auth: Bearer API key created after sign-in
### Headers
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| Authorization | string | yes | Bearer API key created in the account after sign-in |
### Path params
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| taskId | number | yes | taskId returned when the task was created |
No request body.
### Response
`object`
### Response fields
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| status | string | yes | NEW, IN_PROGRESS, PENDING, REJECTED, COMPLETED, or DELETED |
| keyword | string | yes | Anchor text |
| targetUrl | string | yes | Page that should receive the placement |
| resultUrl | string | no | Published placement URL. Present when the task has a result |
| warrantyUpTo | string | no | ISO timestamp. Present when a warranty end is stored |
| createdAt | string | yes | ISO timestamp |
| updatedAt | string | yes | ISO timestamp |
### Request
```
curl -sS https://api.forumbacklinks.org/v1/tasks/20505/status \
-H "Authorization: Bearer your_key"
```
### Response example
```
{
"status": "COMPLETED",
"keyword": "apply for immortality",
"targetUrl": "https://www.macleod.com/immortality-application",
"resultUrl": "https://www.theimmortals.club/threads/how-to-join-the-highlanders.112358/",
"warrantyUpTo": "2025-10-23T10:10:32.812Z",
"createdAt": "2025-09-22T09:53:11.270Z",
"updatedAt": "2025-09-23T10:10:32.880Z"
}
```
Poll with the task id returned by create. Statuses: NEW, IN_PROGRESS, PENDING, REJECTED, COMPLETED, DELETED. resultUrl and warrantyUpTo are omitted until they are stored. Unknown task returns 404.
<a id="delete-task"></a>
## Delete a task
`DELETE` `200` `/v1/tasks/{taskId}`
You can delete a task only while its status is NEW. Any other status cannot be deleted, because our team has already taken that task into work.
Auth: Bearer API key created after sign-in
### Headers
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| Authorization | string | yes | Bearer API key created in the account after sign-in |
### Path params
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| taskId | number | yes | taskId of a NEW task |
No request body.
### Response
`object`
### Response fields
| Name | Type | Required | Description |
| --- | --- | --- | --- |
| message | string | yes | Link task deleted successfully |
### Request
```
curl -sS -X DELETE https://api.forumbacklinks.org/v1/tasks/20505 \
-H "Authorization: Bearer your_key"
```
### Response example
```
{
"message": "Link task deleted successfully"
}
```
Only status NEW can be deleted. Any other status returns 400, because that task is already in work with our team. After a successful delete, GET status returns DELETED.