Integration Quickstart
This guide walks through a complete integration: creating a PAT, listing repositories, starting a runner, monitoring it, and running a routine now.
Prerequisites
- A Forkline account with at least one repository connected
curlor any HTTP client
Client Libraries
The Forkline API is a standard REST API. You can use any HTTP client in your language of choice. Below are examples in Python and TypeScript alongside the curl commands used throughout this guide.
Python
import requests
BASE_URL = "https://api.forkline.dev/v1"
headers = {"Authorization": f"Bearer {TOKEN}"}
# List repositories
resp = requests.get(f"{BASE_URL}/repositories", headers=headers)
repos = resp.json()["repositories"]
# Start a runner
resp = requests.post(
f"{BASE_URL}/repositories/{repo_id}/runners",
headers={**headers, "Content-Type": "application/json"},
json={"name": "my-runner", "size": "basic"},
)
runner = resp.json()
# Poll runner status
resp = requests.get(f"{BASE_URL}/runners/{runner['id']}", headers=headers)
print(resp.json()["status"])
TypeScript
const BASE_URL = "https://api.forkline.dev/v1";
const headers = { Authorization: `Bearer ${TOKEN}` };
// List repositories
const listResp = await fetch(`${BASE_URL}/repositories`, { headers });
const { repositories } = await listResp.json();
// Start a runner
const startResp = await fetch(`${BASE_URL}/repositories/${repoId}/runners`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({ name: "my-runner", size: "basic" }),
});
const runner = await startResp.json();
// Poll runner status
const statusResp = await fetch(`${BASE_URL}/runners/${runner.id}`, { headers });
const { status } = await statusResp.json();
Info: The official Forkline CLI provides a command-line interface for all API operations. No SDK packages (npm, crates.io) are published yet — the examples above use plain HTTP clients. The OpenAPI specification can be used to generate typed clients with tools like openapi-generator, Hey API (
@hey-api/openapi-tsfor TypeScript), or oapi-codegen for Go.
Step 1: Create a Personal Access Token
- Log in to the Forkline web application
- Go to Settings → API Tokens
- Click Create Token
- Select the scopes you need (for this guide:
repositories:read,runners:read,runners:write,routines:read,routines:execute) - Copy the token — it is shown only once
Export it for the examples below:
export FORKLINE_TOKEN="fl_pat_v1_..."
See Authentication for full details on scopes and token management.
Step 2: List Your Repositories
curl -H "Authorization: Bearer $FORKLINE_TOKEN" \
https://api.forkline.dev/v1/repositories
Response:
{
"repositories": [
{
"id": "a1b2c3d4-...",
"name": "my-project",
"owner": "octocat",
"repository_url": "https://github.com/octocat/my-project",
"connector_id": "f0e1d2c3-...",
"default_runner_size": "basic",
"trigger_policy": "open",
"allowed_users": [],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-09-01T08:00:00Z"
}
],
"total": 1,
"offset": 0,
"limit": 50,
"has_more": false
}
Save the repository id for the next steps.
Step 3: Start a Runner
curl -X POST \
-H "Authorization: Bearer $FORKLINE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "api-test-runner", "size": "basic"}' \
https://api.forkline.dev/v1/repositories/<repository_id>/runners
Response (201 Created):
{
"id": "r4n5n6r7-...",
"short": "r4n5",
"repository_id": "a1b2c3d4-...",
"name": "api-test-runner",
"status": "starting",
"source": "manual",
"size": "basic",
"created_at": "2026-09-18T14:20:00Z"
}
Note: Starting a runner requires sufficient credits. If credits are insufficient, the API returns
402 INSUFFICIENT_CREDITS.
Step 4: Monitor the Runner
Poll the runner status:
curl -H "Authorization: Bearer $FORKLINE_TOKEN" \
https://api.forkline.dev/v1/runners/<runner_id>
Check the event history:
curl -H "Authorization: Bearer $FORKLINE_TOKEN" \
https://api.forkline.dev/v1/runners/<runner_id>/events
Response:
{
"events": [
{
"id": "evt-...",
"runner_id": "r4n5n6r7-...",
"event_type": "started",
"new_status": "running",
"details": {},
"created_at": "2026-09-18T14:20:30Z"
}
]
}
Step 5: Run a Routine Now
Run now requires the routines:execute scope and a published or disabled routine. Creating and publishing need routines:write. A webhook routine must select one of your repositories (replace octocat/my-project below), otherwise create answers 422. Create one first. on.webhook: {} means the default token authentication, and the response contains the secret once. (That secret is for the systems that call the webhook URL; Run now does not use it.)
curl -X POST \
-H "Authorization: Bearer $FORKLINE_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "deploy-staging",
"spec": {
"on": {"webhook": {}},
"repositories": {"include": [{"name": "octocat/my-project"}]},
"agent": {"prompt": "Deploy {{ repository.fullName }} to staging. Note: {{ payload.text }}"}
}
}' \
https://api.forkline.dev/v1/routines
curl -X POST -H "Authorization: Bearer $FORKLINE_TOKEN" \
https://api.forkline.dev/v1/routines/<routine_id>/publish
The payload you send is available in the prompt as payload.*, as it is for a webhook call. The routine definition is described under POST /v1/routines. Preview first with "dry_run": true: it writes nothing and shows what would start and the most it can cost.
curl -X POST \
-H "Authorization: Bearer $FORKLINE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"payload": {"text": "Deploy to staging"}}' \
https://api.forkline.dev/v1/routines/<routine_id>/run
Response:
{
"dry_run": false,
"event_id": "0000000e-0000-4000-8000-000000000001",
"targets": [
{
"repository": {"id": "0000000a-0000-4000-8000-000000000001", "full_name": "octocat/my-project"},
"outcome": "task_created",
"task_id": "t1a2b3c4-...",
"session_url": "/sessions/t1a2b3c4-...",
"reason": "Started a run for `octocat/my-project`."
}
],
"estimate": {"runs": 1, "credits_per_run_max": 30, "credits_max": 30},
"task_ids": ["t1a2b3c4-..."],
"session_urls": ["/sessions/t1a2b3c4-..."]
}
See POST /v1/routines/{id}/run for schedule and event routines, subsets and errors.
Step 6: Poll Routine Tasks
Check the tasks created by the routine:
curl -H "Authorization: Bearer $FORKLINE_TOKEN" \
https://api.forkline.dev/v1/routines/<routine_id>/tasks
Response:
{
"tasks": [
{
"id": "t1a2b3c4-...",
"status": "running",
"task_type": "generic",
"repository_url": "https://github.com/octocat/my-project",
"created_at": "2026-09-18T14:25:00Z",
"completed_at": null,
"error_message": null
}
]
}
Poll this endpoint until status is completed or failed.
What’s Next
- Endpoints — full reference with request/response examples
- Authentication — scopes, token management, best practices
- Errors — error codes and handling patterns
What’s Not in the Public API
The following features are only available through the Forkline web application and are not exposed in the public API v1:
- Billing write operations (subscription changes, credit purchases)
- API token self-management via browser session (create/revoke tokens via the web UI or app-domain API)
- Connector configuration (GitHub/GitLab/Forgejo setup)
- Custom AI provider configuration and OpenCode auth setup
These are tracked as separate enhancement requests.