Skip to main content
POST
/
api
/
proposals
Create Proposal
curl --request POST \
  --url https://api.example.com/api/proposals \
  --header 'Content-Type: application/json' \
  --data '
{
  "title": "<string>",
  "description": "<string>",
  "template_id": "<string>"
}
'
{
  "proposal": {
    "id": "<string>",
    "proposalCode": "<string>",
    "title": "<string>",
    "description": "<string>",
    "template_id": "<string>",
    "status": "<string>",
    "created_at": "<string>",
    "updated_at": "<string>",
    "user_id": "<string>",
    "user_email": "<string>",
    "user_name": "<string>",
    "uploaded_files": {},
    "text_inputs": {},
    "metadata": {},
    "completed_steps": [
      {}
    ],
    "step_completion": {}
  },
  "message": "<string>"
}

Authentication

This endpoint requires authentication via Bearer token.
Authorization: Bearer <token>

Request Body

title
string
required
The title of the proposal.
description
string
default:""
Optional description of the proposal.
template_id
string
Optional template ID to use for the proposal.

Response

proposal
object
The created or existing proposal object.
message
string
Optional message, present when returning an existing draft (“Returning existing draft proposal”).

Example Request

cURL
curl -X POST https://api.igadregion.org/api/proposals \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Climate Resilience in East Africa",
    "description": "Proposal for improving climate adaptation strategies"
  }'

Response Examples

{
  "proposal": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "proposalCode": "PROP-20260304-A1B2",
    "title": "Climate Resilience in East Africa",
    "description": "Proposal for improving climate adaptation strategies",
    "template_id": null,
    "status": "draft",
    "created_at": "2026-03-04T10:30:00.000Z",
    "updated_at": "2026-03-04T10:30:00.000Z",
    "user_id": "user_123",
    "user_email": "[email protected]",
    "user_name": "John Doe",
    "uploaded_files": {},
    "text_inputs": {},
    "metadata": {},
    "completed_steps": [],
    "step_completion": {
      "step_1": {
        "completed": false,
        "has_rfp": false,
        "has_concept": false,
        "has_references": false
      },
      "step_2": {
        "completed": false,
        "rfp_analysis_status": "pending",
        "concept_analysis_status": "pending",
        "has_concept_document": false
      },
      "step_3": {
        "completed": false,
        "template_status": "pending",
        "has_template": false,
        "has_generated_content": false
      },
      "step_4": {
        "completed": false,
        "feedback_status": "pending",
        "has_feedback": false
      }
    }
  }
}

Notes

  • One Draft Per User: The system enforces a single draft proposal per user. If you call this endpoint when a draft already exists, you’ll receive the existing draft instead of creating a new one.
  • Proposal Code: The proposalCode is automatically generated in the format PROP-YYYYMMDD-XXXX where YYYYMMDD is the creation date and XXXX is a random suffix.
  • Step Completion: The completed_steps array and step_completion object are computed based on actual data presence and provide a persistent tracking of proposal progress.
  • User Information: The authenticated user’s ID, email, and name are automatically attached to the proposal.

Build docs developers (and LLMs) love