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
{
"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"
}
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
}
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
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
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
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
POST /applications/{application_id}/review¶
Move a submitted application to under_review status.
Authentication: Required
POST /applications/{application_id}/approve¶
Approve an application under review. Optionally specify the approved funding amount.
Authentication: Required
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
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
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
{
"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"
}
POST /applications/{application_id}/generate-stream¶
Generate AI content with real-time Server-Sent Events streaming.
Authentication: Required
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
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) |