Plan a project with structured output
Have a model break a project into tasks, each with an objective, checkable acceptance criteria, dependencies, and an estimate, as JSON you can sort and check, then save the plan as a Bike4Mind project.
- Verified
- Every example run against the live API on
- Endpoints
POST /api/ai/v1/completions,POST /api/v1/projects,DELETE /api/v1/projects/{id}- Key scopes
ai:chat,projects:write- Model
claude-haiku-4-5-20251001- Written in
- curl
A project plan is easier to trust when every piece of it can be checked. This guide asks a model to break a project into tasks: one shippable outcome each, with an objective, acceptance criteria you can tick off, the tasks it depends on, and an estimate in days. The output is JSON that matches a schema, so the plan can be sorted, summed, and argued with before anyone starts work.
You need curl and jq.
Create an API key
In the Bike4Mind app, open your profile, go to the API Keys tab, and click Create API Key. Give it AI Chat for the planning call and Write Projects if you want to save the plan in the last step.
export B4M_API_KEY="b4m_live_<your key>"
Ask for the plan
The system message sets the rules for a good task. The schema makes the model return exactly the
fields the rules ask for. The pipeline after curl joins the streamed content events into one
JSON document and saves it as plan.json.
curl -sN -X POST "https://app.bike4mind.com/api/ai/v1/completions" \
-H "Authorization: Bearer $B4M_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON' | grep '^data: {' | sed 's/^data: //' | jq -rs '[.[] | select(.type == "content") | .text] | join("")' > plan.json
{
"model": "claude-haiku-4-5-20251001",
"messages": [
{
"role": "system",
"content": "You are a project manager. Break the project into 4 to 7 tasks. Each task is one shippable outcome a single person can finish in at most five days, with a concrete objective and checkable acceptance criteria. Use depends_on to name the ids of tasks that must finish first."
},
{
"role": "user",
"content": "Project: add single sign-on (SAML) to our B2B web app. Team: two engineers. Deadline: six weeks."
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "project_plan",
"schema": {
"type": "object",
"properties": {
"tasks": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"title": { "type": "string" },
"objective": { "type": "string" },
"acceptance_criteria": { "type": "array", "items": { "type": "string" } },
"depends_on": { "type": "array", "items": { "type": "string" } },
"estimate_days": { "type": "integer" }
},
"required": ["id", "title", "objective", "acceptance_criteria", "depends_on", "estimate_days"]
}
},
"risks": { "type": "array", "items": { "type": "string" } }
},
"required": ["tasks", "risks"]
}
}
}
}
JSON
The first two of the seven tasks it returned:
{
"tasks": [
{
"id": "saml-design",
"title": "Design SAML integration architecture",
"objective": "Create detailed technical design for SAML authentication flow, including identity provider (IdP) integration points, attribute mapping, and session management",
"acceptance_criteria": [
"Architecture diagram showing SAML flow between app, IdP, and users",
"Specification of required SAML attributes and their mapping to user profiles",
"Session management and token refresh strategy documented",
"Security considerations and risk mitigations identified",
"Design reviewed and approved by team"
],
"depends_on": [],
"estimate_days": 3
},
{
"id": "saml-library-setup",
"title": "Set up SAML library and IdP configuration",
"objective": "Integrate SAML library into the web app and configure test identity provider",
"acceptance_criteria": [
"SAML library (e.g., python3-saml, @node-saml/node-saml) integrated into app",
"Service provider metadata generated and validated",
"Test IdP (e.g., Okta dev account or similar) configured with test users",
"Basic SAML request/response flow working in development environment",
"Integration documented with setup instructions"
],
"depends_on": [
"saml-design"
],
"estimate_days": 3
}
]
}
It also returned eight risks, starting with "IdP configuration complexity varies by customer - may require additional support time" and "SAML library bugs or version incompatibilities could cause delays".
Check the plan
Because the plan is data, the review is a few jq lines. List the tasks in order with their
estimates and dependencies:
jq -r '.tasks[] | "\(.id)\t\(.estimate_days)d\t\(.title)\tafter: \(.depends_on | join(", "))"' plan.json
saml-design 3d Design SAML integration architecture after:
saml-library-setup 3d Set up SAML library and IdP configuration after: saml-design
saml-auth-flow 4d Implement SAML authentication flow after: saml-library-setup
saml-user-provisioning 3d Implement user attribute mapping and provisioning after: saml-auth-flow
saml-testing 3d Test SAML integration with multiple scenarios after: saml-user-provisioning
saml-customer-docs 2d Create SAML integration documentation and customer guides after: saml-testing
saml-security-audit 3d Conduct security audit and production hardening after: saml-customer-docs
This is where the plan earns its keep. Every task depends on the one before it, so the seven tasks form a single chain of 21 working days. That fits six weeks, but it leaves the second engineer nothing to do in parallel. The model followed the rules it was given and nothing more. Add the constraint you care about ("two engineers should be able to work at the same time; minimize the longest dependency chain") to the system message and ask again.
Save it as a project
A Bike4Mind project groups sessions and files, so the plan can live next to the work. Build the
request body from plan.json with jq, then create the project:
jq -n --slurpfile p plan.json '{name: "SAML SSO (guide test)", description: ($p[0].tasks | map("\(.id): \(.title)") | join("\n"))}' > proj.json
curl -s -X POST "https://app.bike4mind.com/api/v1/projects" \
-H "Authorization: Bearer $B4M_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @proj.json
It answers 201 Created with the new project:
{
"id": "6aca8a1ed11421b3b36ae521",
"name": "SAML SSO (guide test)",
"description": "saml-design: Design SAML integration architecture\nsaml-library-setup: Set up SAML library and IdP configuration\nsaml-auth-flow: Implement SAML authentication flow\nsaml-user-provisioning: Implement user attribute mapping and provisioning\nsaml-testing: Test SAML integration with multiple scenarios\nsaml-customer-docs: Create SAML integration documentation and customer guides\nsaml-security-audit: Conduct security audit and production hardening",
"session_ids": [],
"file_ids": [],
"created_at": "2026-10-10T18:55:26.787Z",
"updated_at": "2026-10-10T18:55:26.787Z"
}
The name must be unique among your projects, and the body rejects fields it does not know. To remove
the project, delete it by the id from that response. Only the owner can, and the sessions and
files it grouped are kept:
PROJECT_ID="<id from the response>"
curl -s -X DELETE "https://app.bike4mind.com/api/v1/projects/$PROJECT_ID" \
-H "Authorization: Bearer $B4M_API_KEY" \
-w "%{http_code}\n"
204
Where to take it
- Make the rules yours. "At most five days" and "checkable acceptance criteria" are in the system message because they make a plan reviewable. Replace them with your team's definition of done.
- Check before you trust. Validate that every id in
depends_onexists and that the graph has no cycles before you hand the plan to anyone. The schema guarantees the shape, not the logic. - One task per issue. Each task maps cleanly onto a tracker issue: the title, the objective as the body, the acceptance criteria as a checklist.
Something here no longer matches what the API returns? Tell us at support@bike4mind.com and we will rerun it. Full endpoint reference: API explorer.