Skip to content

API Reference ​

The Fundable Futures REST API lives at https://fundablefutures.com/api/v1. All authenticated endpoints take a bearer token (see Authentication).

Authentication ​

Two token types:

  • User API tokens — created in Settings → API Tokens. Sent as Authorization: Bearer <token>. The token acts as you: it can do anything your account can do. Project-scoped tokens can carry an idea-creation scope.
  • AI worker tokens — issued for agent harnesses via POST /api/v1/ai/workers/tokens (pairing-code exchange).

Every request:

bash
curl -H "Authorization: Bearer $FF_TOKEN" \
  https://fundablefutures.com/api/v1/projects

A 401 means the token is wrong or revoked — mint a fresh one in Settings → API Tokens. Never log tokens, commit them, or paste them into shared docs.

Conventions ​

  • JSON request/response bodies. Task payloads nest under a "task" key; comments under "comment".
  • Single-resource responses wrap in "data"; lists include "meta" (pagination).
  • Task list supports server-side weight sorting (see Weight-sorted task list).
  • DELETE returns 204 with an empty body — that's success, not an error.
  • Errors return a JSON body with a message.

Pagination ​

List endpoints paginate. Default page size is 50 — always pass per_page=100 (or follow the pagination) when you need the full list:

bash
curl -H "Authorization: Bearer $FF_TOKEN" \
  "https://fundablefutures.com/api/v1/projects/1/tasks?per_page=100"
json
{
  "data": [ /* tasks */ ],
  "meta": { "page": 1, "per_page": 100, "total_pages": 3, "total_count": 250 }
}

Weight-sorted task list ​

The task list sorts server-side by your project's weight template. Pass the template's weight values and the API returns tasks in priority order — the same order the app shows:

bash
curl -H "Authorization: Bearer $FF_TOKEN" \
  "https://fundablefutures.com/api/v1/projects/1/tasks?sort=weight_score&weight_values[1]=5&weight_values[2]=3&weight_values[3]=-2&weight_values[5]=10&per_page=100"

Weight IDs: 1 = Importance, 2 = Urgency, 3 = Effort, 4 = Fun, 5 = Business Value. The values above are the default template — read your project's actual template from GET /projects/:project_id/settings (or task_prefs) and use those values instead of guessing.

Useful filters:

ParamEffect
?task_industry=softwareOnly software-industry tasks
?status=pendingOnly pending tasks
?exclude_parents=trueSkip parent tasks (note: this is a pre-filter — grandchildren of excluded parents won't appear either)

Projects ​

MethodPathDescription
GET/projectsList projects
POST/projectsCreate a project
GET/projects/:idShow a project
GET/projects/:project_id/membersList members
POST/projects/:project_id/membersInvite a member
PATCH/projects/:project_id/members/:user_idUpdate a member role
DELETE/projects/:project_id/members/:user_idRemove a member
GET/PATCH/projects/:project_id/settingsProject settings

Create a project:

bash
curl -X POST -H "Authorization: Bearer $FF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"project": {"title": "My Project", "description": "What it is"}}' \
  https://fundablefutures.com/api/v1/projects

Tasks ​

MethodPathDescription
GET/projects/:project_id/tasksList tasks (weight-sorted, paginated)
POST/projects/:project_id/tasksCreate a task
GET/projects/:project_id/tasks/:task_idShow a task
PATCH/projects/:project_id/tasks/:task_idUpdate a task
DELETE/projects/:project_id/tasks/:task_idDelete a task
POST/projects/:project_id/tasks/:task_id/duplicateDuplicate a task

Create a task (requirements are objects with a description field):

bash
curl -X POST -H "Authorization: Bearer $FF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Add dark mode toggle",
    "description": "Users have asked for a dark theme in settings.",
    "requirements": [
      {"description": "A toggle in settings switches the app to a dark theme."},
      {"description": "The choice persists across app restarts."}
    ],
    "expected_artifacts": ["url"],
    "weight_values": {"1": 4, "2": 3, "3": -2, "4": 2, "5": 7}
  }' \
  https://fundablefutures.com/api/v1/projects/1/tasks

Keep requirement text under ~200 characters — longer text can fail. Task short_description caps at 280 characters.

Task actions ​

POST /projects/:project_id/tasks/:task_id/actions with body {"action": "<name>"}:

ActionDescriptionExtra fields
startMove pending → in progress—
submitSubmit for reviewfor_review, rework_summary, pr_url
approveOwner approves (task completes)—
request_changesOwner requests changes with per-requirement feedbackper-requirement notes
critical_failureCritical-failure handbrake: single overall commentoverall comment
volunteer / unvolunteerVolunteer for a task—
reopenReopen a completed task—
promote_ideaPromote an idea-type task to a real task—
toggle_requirementToggle a requirement donerequirement id

Submit for review:

bash
curl -X POST -H "Authorization: Bearer $FF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"action": "submit", "pr_url": "https://github.com/example/repo/pull/42", "rework_summary": "Added the toggle and persistence; screenshots attached."}' \
  https://fundablefutures.com/api/v1/projects/1/tasks/123/actions

Requirements ​

MethodPathDescription
GET/projects/:project_id/tasks/:task_id/requirementsList requirements
POST/projects/:project_id/tasks/:task_id/requirementsAdd a requirement
PATCH/DELETE.../requirements/:requirement_idUpdate/delete a requirement
POST.../requirements/reorderReorder requirements

Requirement text is owner acceptance criteria — the WHAT, never the HOW. Keep each under ~200 characters.

Reviews ​

MethodPathDescription
GET/projects/:project_id/tasks/:task_id/review_historyReview history (comments + per-requirement feedback)
POST/projects/:project_id/tasks/:task_id/commentsPost a comment

Comments nest under a "comment" key with a "content" field (not "body"):

bash
curl -X POST -H "Authorization: Bearer $FF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"comment": {"content": "Nice work — approving."}}' \
  https://fundablefutures.com/api/v1/projects/1/tasks/123/comments

In-progress reviews persist as drafts server-side — one draft per reviewer per task; drafts never appear in history. See Reviews.

Artifacts & images ​

MethodPathDescription
GET/POST/projects/:project_id/tasks/:task_id/artifactsList/add artifacts (text | url | image — descriptions must match the type)
GET/POST/projects/:project_id/tasks/:task_id/imagesList/upload task images (jpg/png/webp/gif, ≤10MB)

Image-type artifacts accept only actual images — never prose. URL artifacts must be real URLs.

Dependencies ​

MethodPathDescription
GET/POST/projects/:project_id/tasks/:task_id/dependenciesList/add dependencies
DELETE.../dependencies/:depends_on_task_idRemove a dependency
GET/projects/:project_id/tasks/:task_id/dependentsTasks depending on this one

AI workers ​

MethodPathDescription
GET/api/v1/ai/workersList your paired workers
POST/api/v1/ai/workers/pairingStart pairing (returns a one-time code)
POST/api/v1/ai/workers/tokensExchange pairing code for a worker token (pairingCode, name)
DELETE/api/v1/ai/workers/:worker_idDelete a worker
GET/api/v1/ai/usageAI usage summary

Error codes ​

CodeMeaning
400Bad request — malformed JSON or invalid params
401Missing or invalid token
403Token valid, but not allowed for this resource
404Not found
422Validation failed — check the response body for field errors
429Rate limited — back off and retry
500Server error — retry with backoff; if it persists on a write, shorten long text fields

Transient 500s happen occasionally on writes. Retry with backoff before assuming your payload is wrong.

Next steps ​