Skip to content

Applications API

The Applications API manages the full lifecycle of grant applications, from initial drafting through AI-powered content generation to submission, review, and final decision. Applications follow a Kanban workflow with defined status transitions.

All endpoints require authentication and are scoped to the current user's tenant.


Application Workflow

stateDiagram-v2
    [*] --> draft : Create
    draft --> in_progress : Start editing
    draft --> submitted : Submit
    in_progress --> submitted : Submit
    submitted --> under_review : Begin review
    under_review --> approved : Approve
    under_review --> rejected : Reject
    approved --> [*]
    rejected --> [*]

Status Definitions

Status Description Editable
draft Initial state, application can be freely edited Yes
in_progress Actively being worked on with generated content Yes
submitted Submitted for review, no further edits allowed No
under_review Being reviewed by grant authority No
approved Application approved for funding No
rejected Application rejected No

Editability

Only applications in draft or in_progress status can be updated or have content generated. Submitted and later stages are locked.


CRUD Endpoints

POST /applications

Create a new grant application. Applications start in draft status. Duplicate applications (same company + grant) are prevented.

Authentication: Required

{
  "company_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "grant_id": "b1c2d3e4-f5a6-7890-bcde-f12345678901",
  "requested_amount": 250000,
  "notes": "Initial application for solar panel installation project"
}
{
  "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
  "tenant_id": "660e8400-e29b-41d4-a716-446655440000",
  "company_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "grant_id": "b1c2d3e4-f5a6-7890-bcde-f12345678901",
  "status": "draft",
  "requested_amount": 250000.0,
  "notes": "Initial application for solar panel installation project",
  "generated_content": {},
  "documents": [],
  "is_editable": true,
  "is_submitted": false,
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "company_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "grant_id": "b1c2d3e4-f5a6-7890-bcde-f12345678901",
    "requested_amount": 250000
  }'

Request Body (ApplicationCreate):

Field Type Required Description
company_id UUID Yes Company applying for the grant
grant_id UUID Yes Grant being applied for
requested_amount float No Requested funding amount in EUR
notes string No User notes (max 5000 chars)

Status Codes:

Code Description
201 Application created
400 Duplicate application for this company/grant pair
401 Not authenticated
404 Company not found (wrong tenant) or grant not found

GET /applications

List applications with optional filtering and pagination.

Authentication: Required

{
  "items": [
    {
      "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
      "status": "draft",
      "company_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "grant_id": "b1c2d3e4-f5a6-7890-bcde-f12345678901",
      "requested_amount": 250000.0,
      "is_editable": true,
      "created_at": "2025-01-15T10:30:00Z"
    }
  ],
  "total": 5,
  "page": 1,
  "limit": 20,
  "has_more": false
}
curl -X GET "https://api.carbonconnect.io/api/v1/applications?status=draft&company_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890&page=1&limit=20" \
  -H "Authorization: Bearer <token>"

Query Parameters:

Parameter Type Default Description
company_id UUID -- Filter by company
grant_id UUID -- Filter by grant
status string -- Filter by status: draft, in_progress, submitted, under_review, approved, rejected
page integer 1 Page number
limit integer 20 Items per page (1-100)

GET /applications/{application_id}

Get a single application by ID.

Authentication: Required

curl -X GET https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012 \
  -H "Authorization: Bearer <token>"

Status Codes:

Code Description
200 Application returned
401 Not authenticated
404 Application not found or wrong tenant

PATCH /applications/{application_id}

Update an application. Only editable applications (draft, in_progress) can be updated.

Authentication: Required

{
  "requested_amount": 275000,
  "notes": "Updated amount based on revised project scope"
}
curl -X PATCH https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"requested_amount": 275000}'

Request Body (ApplicationUpdate):

Field Type Required Description
requested_amount float No Updated requested amount (EUR)
notes string No Updated notes (max 5000 chars)
internal_notes string No Internal notes (admin only)

Status Codes:

Code Description
200 Application updated
400 Application is not editable (submitted or later)
404 Application not found or wrong tenant

DELETE /applications/{application_id}

Delete an application. Only draft applications can be deleted.

Authentication: Required

curl -X DELETE https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012 \
  -H "Authorization: Bearer <token>"

Status Codes:

Code Description
204 Application deleted (no response body)
400 Only draft applications can be deleted
404 Application not found or wrong tenant

Status Workflow Endpoints

POST /applications/{application_id}/submit

Submit an application for review. Valid from draft or in_progress status.

Authentication: Required

{
  "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
  "status": "submitted",
  "previous_status": "draft",
  "submitted_at": "2025-01-20T14:00:00Z",
  "message": "Application submitted successfully"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/submit \
  -H "Authorization: Bearer <token>"

POST /applications/{application_id}/review

Move a submitted application to under_review status.

Authentication: Required

{
  "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
  "status": "under_review",
  "previous_status": "submitted",
  "message": "Application moved to review"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/review \
  -H "Authorization: Bearer <token>"

POST /applications/{application_id}/approve

Approve an application under review. Optionally specify the approved funding amount.

Authentication: Required

{
  "approved_amount": 200000,
  "notes": "Approved with reduced scope for Phase 1"
}
{
  "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
  "status": "approved",
  "previous_status": "under_review",
  "decision_at": "2025-02-10T09:00:00Z",
  "approved_amount": 200000.0,
  "message": "Application approved"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/approve \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"approved_amount": 200000}'

Request Body (optional):

Field Type Required Description
approved_amount float No Approved funding amount (EUR)
notes string No Approval notes (max 2000 chars)

POST /applications/{application_id}/reject

Reject an application under review.

Authentication: Required

{
  "rejection_reason": "Project scope does not align with program objectives"
}
{
  "id": "f1a2b3c4-d5e6-7890-abcd-123456789012",
  "status": "rejected",
  "previous_status": "under_review",
  "decision_at": "2025-02-10T09:00:00Z",
  "message": "Application rejected: Project scope does not align with program objectives"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/reject \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"rejection_reason": "Project scope does not align with program objectives"}'

Request Body:

Field Type Required Description
rejection_reason string Yes Reason for rejection (max 2000 chars)

AI Content Generation Endpoints

POST /applications/{application_id}/generate

Generate AI content for a specific application section using Claude.

Authentication: Required

{
  "section": "executive_summary",
  "language": "en",
  "store": true,
  "additional_context": "Focus on the solar panel installation component"
}
{
  "section": "executive_summary",
  "content": "GreenTech Solutions GmbH proposes a comprehensive solar panel installation project...",
  "tokens_used": 1250,
  "generation_time_ms": 2340.5,
  "model": "claude-sonnet-4-20250514",
  "language": "en"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/generate \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"section": "executive_summary", "language": "en", "store": true}'

Request Body (GenerateSectionRequest):

Field Type Required Description
section string Yes Section to generate (see table below)
language string No Output language: en, de, fr (default: en)
store boolean No Store content in application (default: true)
additional_context string No Extra context for generation (max 2000 chars)
requested_amount float No For budget justification section
budget_breakdown object No Budget category breakdown
project_duration_months integer No Project duration (1-60 months)

Supported Sections:

Section Description
executive_summary Project overview and key objectives
methodology Technical approach and implementation
budget_justification Cost breakdown and financial plan
timeline Project milestones and schedule
impact_assessment Expected outcomes and impact metrics

POST /applications/{application_id}/generate-all

Generate AI content for all application sections at once. This may take 10-15 seconds.

Authentication: Required

{
  "language": "en",
  "store": true,
  "sections": ["executive_summary", "methodology", "impact_assessment"],
  "requested_amount": 250000,
  "project_duration_months": 24
}
{
  "sections": {
    "executive_summary": "GreenTech Solutions GmbH proposes...",
    "methodology": "The project will follow a phased approach...",
    "impact_assessment": "The expected impact includes..."
  },
  "total_tokens": 4500,
  "estimated_cost": 0.0045,
  "generation_time_ms": 12500.0,
  "model": "claude-sonnet-4-20250514",
  "language": "en",
  "generated_at": "2025-01-15T10:30:00Z"
}
curl -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/generate-all \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"language": "en", "store": true}'

POST /applications/{application_id}/generate-stream

Generate AI content with real-time Server-Sent Events streaming.

Authentication: Required

curl -N -X POST https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/generate-stream \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"section": "executive_summary", "language": "en"}'

Response: text/event-stream

data: {"event": "chunk", "data": "GreenTech Solutions ", "section": "executive_summary"}

data: {"event": "chunk", "data": "GmbH proposes a ", "section": "executive_summary"}

data: {"event": "chunk", "data": "comprehensive solar panel ", "section": "executive_summary"}

data: {"event": "complete", "section": "executive_summary"}

SSE Event Types:

Event Description
chunk Text chunk as it is generated
complete Generation finished for the section
error An error occurred during generation

GET /applications/{application_id}/estimate-cost

Estimate the cost of generating content for an application before committing.

Authentication: Required

{
  "estimated_cost": 0.005,
  "sections_count": 5,
  "model": "claude-sonnet-4-20250514",
  "currency": "USD"
}
curl -X GET https://api.carbonconnect.io/api/v1/applications/f1a2b3c4-d5e6-7890-abcd-123456789012/estimate-cost \
  -H "Authorization: Bearer <token>"

Response Body:

Field Type Description
estimated_cost float Estimated cost in USD
sections_count integer Number of sections to generate
model string LLM model used for estimation
currency string Cost currency (always USD)