BidRadar Development Progress
██████░░░░░░░░░░░░░░ 6/60
Current phase: Strategy and development foundations
Current milestone: Define the application contracts before generating frontend or backend code
Previous article: Designing the Database Schema
Next article: Establishing the BidRadar Design System and User Experience
Primary deliverable: docs/api-specification.md
API framework: FastAPI
API style: Resource-oriented REST over HTTPS and JSON
Application code generated: None
Introduction
In the previous five articles, we established the foundation for BidRadar.
We defined:
- The product vision
- The target customer
- The development workflow
- The Product Requirements Document
- The high-level system architecture
- The PostgreSQL and pgvector database schema
We now understand:
- What BidRadar must do
- Which users it serves
- How its major components fit together
- Which data must be stored
- How tenant ownership is represented
- Which records require versioning
- Which processes run asynchronously
- Which AI activities require evidence and human review
The next step is to define how the application components communicate.
The React frontend will need to communicate with the FastAPI backend.
Background-processing interfaces will need to expose job status.
Tender-source connectors will need stable internal contracts.
Future Microsoft 365, CRM, and procurement-portal integrations will need controlled access points.
The frontend should not guess:
- How an opportunity is represented
- Which fields are required
- How errors are formatted
- How pagination works
- How organization context is selected
- How long-running jobs report progress
- How versions are handled
- How an AI analysis is requested
- How approval actions are submitted
These decisions belong in an API specification.
This article defines the BidRadar REST API and Application Contracts.
The document we create will act as a boundary between:
- Frontend and backend
- API routes and service logic
- Internal modules and external integrations
- Synchronous requests and background processing
- AI execution requests and persisted results
- Human actions and automated workflows
The goal is not to implement every endpoint yet.
The goal is to create stable, consistent rules that future Google AI Studio prompts must follow when generating:
- FastAPI routers
- Pydantic schemas
- React API clients
- TanStack Query hooks
- Integration tests
- Mock data
- Error handling
- OpenAPI documentation
Objectives
After completing this article, we should have:
- A documented REST API strategy
- API versioning rules
- Resource naming conventions
- Authentication contracts
- Organization-context rules
- Authorization behavior
- Standard request and response envelopes
- Pagination contracts
- Filtering and sorting conventions
- Search conventions
- Error-response formats
- Validation-error formats
- Idempotency rules
- Optimistic-concurrency rules
- Background-job contracts
- File-upload contracts
- Opportunity API contracts
- Tender-document API contracts
- Requirement API contracts
- Analysis and scoring contracts
- Knowledge-base API contracts
- Proposal API contracts
- Compliance API contracts
- Workflow and approval contracts
- Export contracts
- AI execution and usage boundaries
- Audit-access boundaries
- Webhook and integration principles
- A complete Google AI Studio API-design prompt
- A manual review and validation checklist
Why Design the API Before Generating Code?
Google AI Studio could generate React screens and FastAPI endpoints immediately.
That would likely produce working code quickly.
It could also create inconsistencies such as:
- One endpoint using camelCase while another uses snake_case
- Different pagination formats across resources
- Organization IDs supplied in unsafe request bodies
- Raw database models returned directly
- Different error formats for each module
- Long-running AI operations blocking HTTP requests
- Proposal versions overwritten through ordinary update endpoints
- Approval actions mixed into generic patch requests
- File uploads without checksums or processing states
- AI prompts exposed to frontend clients
- Inconsistent status names
- Sensitive audit details returned to unauthorized users
A stable API contract prevents these inconsistencies.
The correct design sequence is:
Product requirements ↓Architecture ↓Database schema ↓API contracts ↓Frontend and backend generation
The API specification becomes the formal agreement between application layers.
API Design Principles
The BidRadar API should follow several core principles.
Principle 1 — Resource-Oriented Design
Primary business concepts should be represented as resources.
Examples include:
- Organizations
- Opportunities
- Documents
- Requirements
- Knowledge documents
- Proposals
- Tasks
- Exports
Principle 2 — Business Actions Are Explicit
Actions with business meaning should not be hidden inside generic updates.
Examples:
POST /opportunities/{id}/bid-decisionsPOST /proposal-sections/{id}/approvePOST /documents/{id}/processPOST /proposals/{id}/exports
Principle 3 — Tenant Context Is Derived Securely
The backend must not trust arbitrary organization ownership supplied in request bodies.
Organization context should be derived from:
- Authenticated user
- Active organization selection
- Verified organization membership
- Resource ownership
Principle 4 — Long-Running Work Is Asynchronous
Operations such as:
- OCR
- Gemini analysis
- Requirement extraction
- Embedding generation
- Proposal drafting
- Compliance validation
- DOCX export
should return a job reference rather than blocking the request until completion.
Principle 5 — Contracts Are Versioned
Breaking changes require a new API version or controlled compatibility strategy.
Principle 6 — Responses Are Predictable
Pagination, errors, metadata, and timestamps should use consistent structures.
Principle 7 — Internal Models Are Not Public Contracts
SQLAlchemy models should not be returned directly.
Pydantic response schemas define the API.
Principle 8 — Sensitive Internal Details Stay Server-Side
Clients should not receive:
- Secret keys
- Provider credentials
- Raw stack traces
- Internal prompt instructions
- Storage credentials
- Unredacted security metadata
API Base URL
The initial API should use a versioned prefix.
/api/v1
Example local URL:
http://localhost:8000/api/v1
Example production URL:
https://api.bidradar.example/api/v1
The actual domain will be configured later.
API Versioning Strategy
The initial version will be:
v1
Versioning applies to externally visible contracts.
Breaking Changes
Examples include:
- Removing a field
- Renaming a field
- Changing a field type
- Changing response structure
- Changing mandatory request fields
- Changing pagination behavior
These require:
- A new API version
- A documented migration
- Or a controlled deprecation period
Non-Breaking Changes
Examples may include:
- Adding an optional response field
- Adding a new endpoint
- Adding an optional filter
- Adding a new enum value where clients are designed to tolerate it
Even non-breaking changes should be documented.
Content Types
Normal JSON requests should use:
Content-Type: application/json
File uploads should use:
multipart/form-data
Downloads should return the appropriate MIME type or a short-lived authorized download URL.
JSON Naming Convention
The recommended external JSON naming convention is:
snake_case
Example:
{ "submission_deadline": "2027-03-15T12:00:00Z", "estimated_value_min": 250000.00, "organization_id": "..."}
This aligns naturally with Python and Pydantic.
The React application can use generated or shared TypeScript types using the same field names.
Consistency is more important than choosing camelCase or snake_case.
Date and Time Format
All timestamps should use ISO 8601.
Example:
2027-03-15T12:00:00Z
Rules:
- Return UTC where practical.
- Include timezone offsets.
- Do not return ambiguous local timestamps.
- Preserve original source text separately where imported deadlines were unclear.
Date-only values should use:
2027-03-15
Monetary Values
Money should be represented using decimal-safe JSON values and explicit currency codes.
Example:
{ "estimated_value_min": "250000.00", "estimated_value_max": "500000.00", "currency": "USD"}
Returning decimal values as strings prevents accidental floating-point corruption across languages.
The final implementation may standardize this through shared money schemas.
Identifier Format
Public resource identifiers should use UUID strings.
Example:
8c1654d1-9f78-49f8-89ed-e5cf577bd28a
Clients should treat identifiers as opaque.
They should not infer:
- Record age
- Tenant
- Sequence
- Resource type
Authentication Contract
The initial API will support email-and-password authentication.
Future versions may add Microsoft Entra ID and other identity providers.
Registration
POST /api/v1/auth/register
Example request:
{ "email": "owner@example.com", "password": "secure-password", "display_name": "Proposal Owner"}
Example response:
{ "user": { "id": "uuid", "email": "owner@example.com", "display_name": "Proposal Owner", "status": "pending_verification" }}
The registration response should not include:
- Password hash
- Verification token
- Internal security fields
Login
POST /api/v1/auth/login
Example request:
{ "email": "owner@example.com", "password": "secure-password"}
Example response:
{ "access_token": "token", "token_type": "bearer", "expires_in": 900, "refresh_token": "refresh-token", "user": { "id": "uuid", "email": "owner@example.com", "display_name": "Proposal Owner" }, "memberships": [ { "organization_id": "uuid", "organization_name": "Example IT Consulting", "role": "owner" } ]}
Refresh-token storage and transport security will be refined during authentication implementation.
Refresh Session
POST /api/v1/auth/refresh
The endpoint should rotate or validate refresh credentials according to the security design.
Logout
POST /api/v1/auth/logout
Logout should invalidate or revoke the relevant refresh session where supported.
Current User
GET /api/v1/auth/me
Example response:
{ "id": "uuid", "email": "owner@example.com", "display_name": "Proposal Owner", "status": "active", "memberships": [ { "organization_id": "uuid", "organization_name": "Example IT Consulting", "role": "owner", "membership_status": "active" } ]}
Organization Context
BidRadar supports tenant-scoped resources.
The API must know which organization the user is operating within.
The recommended pattern is an explicit request header:
X-Organization-ID: <uuid>
The backend must verify:
- The user is authenticated.
- The organization exists.
- The user has an active membership.
- The requested resource belongs to that organization.
- The role permits the requested action.
The header selects context.
It does not grant access.
Why Not Put Organization IDs in Every URL?
An alternative would be:
/organizations/{organization_id}/opportunities
This is explicit but creates long paths throughout the API.
The chosen design can still use organization-scoped routes for administrative resources while using the verified header for primary application resources.
Example:
GET /api/v1/opportunitiesX-Organization-ID: uuid
This keeps resource URLs concise while preserving explicit tenant context.
The final choice must remain consistent.
Organization Endpoints
POST /organizationsGET /organizationsGET /organizations/{organization_id}PATCH /organizations/{organization_id}
Membership endpoints:
GET /organizations/{organization_id}/membersPOST /organizations/{organization_id}/invitationsPATCH /organizations/{organization_id}/members/{membership_id}DELETE /organizations/{organization_id}/members/{membership_id}
Administrative organization routes should validate that the user has sufficient permissions for the target organization.
Authorization Response Behavior
Unauthorized and inaccessible resources must not leak information.
Unauthenticated
Return:
401 Unauthorized
Authenticated but Insufficient Permission
Return:
403 Forbidden
Resource Outside Active Tenant
Depending on security policy, return:
404 Not Found
This can avoid confirming that a resource exists in another organization.
The policy should be consistent and documented.
Standard Resource Metadata
Most resource responses should include:
{ "id": "uuid", "created_at": "2027-03-01T10:00:00Z", "updated_at": "2027-03-02T11:30:00Z"}
Versioned resources may also include:
{ "version_number": 3, "version_token": "opaque-concurrency-token"}
Standard Collection Response
Collections should use a predictable structure.
{ "items": [], "page": { "limit": 25, "offset": 0, "total": 146, "has_more": true }}
For very large or rapidly changing collections, cursor pagination may be preferable.
The initial API can support offset pagination for administrative lists and cursor pagination for activity streams and large data sets.
Pagination Parameters
Standard offset pagination:
limitoffset
Example:
GET /opportunities?limit=25&offset=50
Rules:
- Default limit: 25
- Maximum limit: 100
- Negative values rejected
- Total count may be omitted for expensive queries if documented
Cursor Pagination
Activity feeds, audit events, or notifications may use:
cursorlimit
Example response:
{ "items": [], "next_cursor": "opaque-cursor", "has_more": true}
Cursors must be opaque to clients.
Filtering Convention
Filters should use query parameters.
Example:
GET /opportunities?status=reviewing&country_code=NL
Multiple values can use repeated parameters:
GET /opportunities?status=new&status=reviewing
or comma-separated values if standardized.
Repeated query parameters are easier to represent accurately.
Sorting Convention
Use:
sort
Example:
GET /opportunities?sort=submission_deadlineGET /opportunities?sort=-created_at
Rules:
- A leading minus means descending.
- Only documented fields are sortable.
- Invalid fields return a validation error.
- Stable secondary sorting should be applied internally.
Search Convention
Use:
q
Example:
GET /opportunities?q=azure+migration
Structured filters should remain separate from free-text search.
Example:
GET /opportunities?q=azure&country_code=NL&status=reviewing
Field Selection and Expansion
The initial API should avoid excessive complexity.
Optional controlled expansion may use:
include
Example:
GET /opportunities/{id}?include=buyer,latest_analysis
Expansion should be limited to documented relationships.
Clients should not be allowed to create arbitrary deep joins.
Standard Success Response
Single-resource endpoints may return the resource directly.
Example:
{ "id": "uuid", "title": "Cloud Migration Services", "status": "reviewing"}
Action endpoints may return:
{ "data": { "job_id": "uuid", "status": "queued" }, "message": "Tender analysis was queued."}
The API should not wrap some resources and not others without a clear rule.
A simple approach is:
- Direct resource objects for ordinary CRUD
- Explicit action-result objects for business operations
- Standard collection envelopes for lists
Standard Error Contract
Errors should use one consistent format.
Example:
{ "error": { "code": "opportunity_not_found", "message": "The requested opportunity could not be found.", "request_id": "req_123", "details": null }}
Validation error example:
{ "error": { "code": "validation_error", "message": "The request contains invalid values.", "request_id": "req_123", "details": [ { "field": "submission_deadline", "message": "Submission deadline must be later than publication date.", "type": "value_error" } ] }}
Error-Code Principles
Error codes should be:
- Stable
- Machine-readable
- Lowercase snake_case
- More precise than HTTP status alone
Examples:
authentication_requiredinvalid_credentialsorganization_context_requiredmembership_inactivepermission_deniedopportunity_not_founddocument_type_unsupportedprocessing_already_runningversion_conflictai_provider_unavailableusage_limit_exceeded
HTTP Status Codes
Use standard HTTP semantics.
200 OK
Successful retrieval or update.
201 Created
Resource created.
202 Accepted
Asynchronous operation accepted.
204 No Content
Successful deletion or action without response body.
400 Bad Request
Malformed or semantically invalid request.
401 Unauthorized
Authentication required or invalid.
403 Forbidden
Authenticated but not authorized.
404 Not Found
Resource unavailable within the authorized context.
409 Conflict
Version conflict, duplicate record, or invalid state transition.
413 Payload Too Large
File exceeds allowed size.
415 Unsupported Media Type
Unsupported file format.
422 Unprocessable Entity
Schema validation error.
429 Too Many Requests
Rate or usage limit reached.
500 Internal Server Error
Unexpected application error.
502 Bad Gateway
External provider returned an invalid response.
503 Service Unavailable
Dependency temporarily unavailable.
Request Correlation
Every API response should expose a request identifier.
Example header:
X-Request-ID: req_123
Clients should display or record this identifier when reporting errors.
Background jobs should also use correlation IDs linking:
- Initial request
- Job
- Worker logs
- Gemini execution
- Persisted result
Idempotency
Certain POST operations may be retried by clients.
Examples include:
- Creating an opportunity from an external event
- Starting a document upload
- Requesting an export
- Submitting a Bid/No-Bid approval
The API should support:
Idempotency-Key: <client-generated-value>
The backend should scope idempotency by:
- Organization
- User or client
- Endpoint
- Key
Repeated equivalent requests should return the original result where practical.
Optimistic Concurrency
Collaborative and versioned resources must protect against lost updates.
Clients should submit a version token or revision number.
Example header:
If-Match: "version-token"
or request field:
{ "expected_version": 4}
If the stored version changed, return:
409 Conflict
Example error code:
version_conflict
This is particularly important for:
- Opportunity updates
- Requirement edits
- Proposal-section edits
- Organization settings
- Workflow tasks
Soft Deletion API Behavior
Ordinary deletion endpoints should generally archive or soft-delete records where history matters.
Example:
DELETE /opportunities/{id}
Possible response:
204 No Content
The implementation may set deleted_at rather than physically removing the record.
Restore endpoints may be introduced for authorized administrators.
Permanent deletion should use specialized administrative workflows.
Background Job Contract
Long-running operations should return:
202 Accepted
Example response:
{ "job": { "id": "uuid", "job_type": "requirement_extraction", "status": "queued", "resource_type": "opportunity", "resource_id": "uuid", "progress_percent": 0, "created_at": "2027-03-01T10:00:00Z" }}
Job Status Endpoint
GET /jobs/{job_id}
Example response:
{ "id": "uuid", "job_type": "requirement_extraction", "status": "running", "progress_percent": 65, "attempt_count": 1, "started_at": "2027-03-01T10:01:00Z", "completed_at": null, "result": null, "error": null}
Completed example:
{ "id": "uuid", "status": "completed", "progress_percent": 100, "result": { "resource_type": "requirement_batch", "resource_id": "uuid" }}
Job Error Contract
{ "id": "uuid", "status": "failed", "error": { "code": "document_extraction_failed", "message": "Text could not be extracted from the uploaded document.", "retryable": true }}
The frontend should not receive raw provider errors.
Cancelling Jobs
Where safe:
POST /jobs/{job_id}/cancel
Cancellation may be unavailable after an irreversible processing stage.
The API should return a conflict if cancellation is not possible.
File-Upload Contract
The document-upload workflow should separate registration, transfer, and processing where practical.
For the MVP, a direct multipart endpoint is acceptable.
POST /opportunities/{opportunity_id}/documentsContent-Type: multipart/form-data
Fields:
filedocument_typetitle
Example response:
{ "document": { "id": "uuid", "title": "Technical Specification", "document_type": "technical_specification", "status": "uploaded", "current_version": { "id": "uuid", "original_filename": "technical-specification.pdf", "mime_type": "application/pdf", "file_size_bytes": 3259184, "checksum_sha256": "..." } }, "processing_job": { "id": "uuid", "status": "queued" }}
Upload Validation
The API must validate:
- Organization permission
- Opportunity ownership
- File size
- File type
- MIME type
- File name
- Checksum
- Malware-scanning policy hook
- Duplicate status where relevant
Direct-to-Storage Uploads
A later optimized flow may use:
POST /documents/upload-sessions
Response:
{ "upload_session_id": "uuid", "upload_url": "short-lived-authorized-url", "expires_at": "..."}
After upload:
POST /documents/upload-sessions/{id}/complete
Permanent storage credentials must never be returned.
Opportunity API
List Opportunities
GET /opportunities
Supported filters may include:
statusowner_user_idbuyer_idcountry_codepublication_date_frompublication_date_tosubmission_deadline_fromsubmission_deadline_toestimated_value_minestimated_value_maxcurrencyclassification_codeqsortlimitoffset
Create Opportunity
POST /opportunities
Example request:
{ "title": "Cloud Infrastructure Modernization", "buyer_id": "uuid", "external_reference": "RFP-2027-102", "description": "Modernization of public-sector cloud infrastructure.", "publication_date": "2027-03-01", "submission_deadline": "2027-04-15T12:00:00Z", "estimated_value_min": "500000.00", "estimated_value_max": "1000000.00", "currency": "USD", "country_code": "US"}
The client should not supply organization_id in the body.
Get Opportunity
GET /opportunities/{opportunity_id}
The response may include links or summary references to:
- Buyer
- Documents
- Requirements
- Latest analysis
- Latest score
- Current Bid decision
- Proposal
- Processing state
Large nested collections should remain separate endpoints.
Update Opportunity
PATCH /opportunities/{opportunity_id}
Use partial updates.
Immutable source fields may require specialized endpoints or permissions.
Concurrency controls should apply.
Archive Opportunity
POST /opportunities/{opportunity_id}/archive
Explicit action endpoints may be clearer than generic deletion when lifecycle meaning matters.
Opportunity Documents
GET /opportunities/{opportunity_id}/documentsPOST /opportunities/{opportunity_id}/documents
Opportunity Requirements
GET /opportunities/{opportunity_id}/requirements
Opportunity Analysis
GET /opportunities/{opportunity_id}/analysesPOST /opportunities/{opportunity_id}/analyses
Example request:
{ "analysis_type": "executive_briefing", "document_version_ids": [ "uuid", "uuid" ]}
Response:
202 Accepted
with a job reference.
Opportunity Score
GET /opportunities/{opportunity_id}/scoresPOST /opportunities/{opportunity_id}/scores
Scoring requests may allow selected configuration:
{ "scoring_profile_id": "uuid", "include_ai_analysis": true}
Weights should not be accepted arbitrarily from unauthorized users.
Bid Decision Contract
Create a decision:
POST /opportunities/{opportunity_id}/bid-decisions
Example request:
{ "decision": "bid_with_conditions", "opportunity_score_id": "uuid", "reason": "Strong technical fit, subject to partner confirmation.", "conditions": [ "Confirm subcontractor availability", "Complete security certification review" ]}
The backend records the authenticated human actor.
Tender Document API
GET /documents/{document_id}PATCH /documents/{document_id}POST /documents/{document_id}/versionsPOST /documents/{document_id}/processGET /documents/{document_id}/extractionsPOST /documents/{document_id}/archive
Download:
GET /document-versions/{document_version_id}/download
The response may redirect to or return a short-lived authorized URL.
Document Extraction Response
{ "id": "uuid", "document_version_id": "uuid", "status": "completed", "processor_type": "pdf_native", "processor_version": "1.0", "page_count": 142, "character_count": 385921, "language_code": "en", "quality_score": 0.97, "created_at": "..."}
Extracted content may use separate paginated endpoints.
GET /document-extractions/{id}/pages
Requirement API
List Requirements
GET /opportunities/{opportunity_id}/requirements
Filters:
categorymandatory_levelstatusreviewedq
Create Requirement Manually
POST /opportunities/{opportunity_id}/requirements
Example request:
{ "title": "ISO 27001 Certification", "requirement_text": "The supplier must maintain ISO 27001 certification.", "category": "security", "mandatory_level": "mandatory", "response_type": "evidence", "evidence_expected": "Valid ISO 27001 certificate"}
Origin should be recorded as human-created.
Start Requirement Extraction
POST /opportunities/{opportunity_id}/requirement-extractions
Example request:
{ "document_version_ids": [ "uuid", "uuid" ], "extraction_profile": "standard_tender_requirements"}
Response:
202 Accepted
Get Requirement
GET /requirements/{requirement_id}
Include:
- Current accepted content
- Source reference
- Confidence
- Review status
- Version summary
Edit Requirement
POST /requirements/{requirement_id}/versions
Creating a new version is safer than overwriting accepted text.
Example request:
{ "requirement_text": "Updated reviewed requirement text.", "category": "security", "mandatory_level": "mandatory", "change_summary": "Clarified certificate validity requirement.", "expected_version": 2}
Review Requirement
POST /requirements/{requirement_id}/reviews
Example request:
{ "decision": "accepted", "comments": "Confirmed against page 32 of the specification."}
Possible decisions:
acceptededitedrejected
Analysis API
Analysis resources should expose versioned records.
GET /analyses/{analysis_id}GET /opportunities/{opportunity_id}/analyses
The response should include:
- Type
- Version
- Status
- Structured result
- Confidence
- Evidence references
- AI execution metadata summary
- Human review status
It should not expose private system prompts.
Knowledge API
List Knowledge Documents
GET /knowledge-documents
Filters:
knowledge_typestatussecurity_classificationowner_user_ideffective_atq
Upload Knowledge Document
POST /knowledge-documents
Multipart fields:
fileknowledge_typetitledescriptionsecurity_classification
Response includes:
- Knowledge document
- Initial version
- Processing job
Review Knowledge Metadata
PATCH /knowledge-documents/{knowledge_document_id}
Approve Knowledge Version
POST /knowledge-versions/{version_id}/approve
Example request:
{ "comments": "Approved for proposal evidence use."}
Archive Knowledge Document
POST /knowledge-documents/{id}/archive
Search Knowledge
POST /knowledge-search
A POST request is appropriate because search may include a structured body.
Example request:
{ "query": "Azure migration experience for healthcare customers", "search_mode": "hybrid", "filters": { "knowledge_types": [ "case_study", "project_reference" ], "technologies": [ "Microsoft Azure" ], "industries": [ "Healthcare" ], "approval_status": "approved" }, "limit": 10}
Example response:
{ "results": [ { "knowledge_chunk_id": "uuid", "knowledge_document_id": "uuid", "title": "Healthcare Azure Migration", "heading": "Project Outcomes", "content_excerpt": "...", "semantic_score": 0.91, "keyword_score": 0.72, "combined_score": 0.88, "source_reference": "Page 4", "metadata": { "industry": "Healthcare", "technology": "Microsoft Azure" } } ], "search_metadata": { "query_id": "uuid", "search_mode": "hybrid", "latency_ms": 184 }}
Permission filtering must happen server-side.
Proposal API
Create Proposal
POST /opportunities/{opportunity_id}/proposals
Example request:
{ "title": "Response to Cloud Infrastructure Modernization RFP", "template_key": "standard_it_services"}
Get Proposal
GET /proposals/{proposal_id}
Response may include:
- Proposal metadata
- Status
- Owner
- Section summary
- Requirement coverage summary
- Pending approvals
- Latest compliance status
List Proposal Sections
GET /proposals/{proposal_id}/sections
Return hierarchy and ordering.
Create Proposal Outline
POST /proposals/{proposal_id}/outline-generations
Example request:
{ "requirement_ids": [ "uuid", "uuid" ], "template_key": "standard_it_services", "include_contributor_recommendations": true}
Response:
202 Accepted
Create or Update Section Structure
POST /proposals/{proposal_id}/sectionsPATCH /proposal-sections/{section_id}
Structural updates should not overwrite section content versions.
Generate Proposal Section Draft
POST /proposal-sections/{section_id}/draft-generations
Example request:
{ "requirement_ids": [ "uuid" ], "knowledge_chunk_ids": [], "generation_profile": "evidence_backed_standard", "instructions": "Emphasize phased migration and service continuity."}
The backend may retrieve evidence automatically.
User-supplied knowledge chunk IDs must still be authorized.
Get Section Versions
GET /proposal-sections/{section_id}/versions
Create Human-Edited Version
POST /proposal-sections/{section_id}/versions
Example request:
{ "content": "Reviewed proposal content...", "content_format": "markdown", "change_summary": "Added delivery governance and transition detail.", "expected_version": 5}
Approve Proposal Section
POST /proposal-sections/{section_id}/approve
Example request:
{ "version_id": "uuid", "comments": "Technical review completed."}
The version must belong to the section and active organization.
Request Changes
POST /proposal-sections/{section_id}/request-changes
Lock and Unlock Section
POST /proposal-sections/{section_id}/locksDELETE /proposal-sections/{section_id}/locks/{lock_id}
Locks should be temporary and separately authorized.
Comments API
GET /proposal-sections/{section_id}/commentsPOST /proposal-sections/{section_id}/commentsPOST /comments/{comment_id}/resolve
Threaded replies may use:
{ "content": "Please add stronger evidence for this claim.", "parent_comment_id": "uuid"}
Reviews API
POST /proposal-sections/{section_id}/reviewsGET /proposal-sections/{section_id}/reviewsPOST /reviews/{review_id}/complete
Review completion request:
{ "decision": "changes_requested", "comments": "Clarify the identity and access-management approach."}
Compliance API
Start validation:
POST /proposals/{proposal_id}/compliance-runs
Example request:
{ "proposal_section_version_policy": "latest_approved_or_current", "include_ai_semantic_review": true}
Response:
202 Accepted
List runs:
GET /proposals/{proposal_id}/compliance-runs
Get findings:
GET /compliance-runs/{run_id}/findings
Filters:
severityfinding_typecoverage_statusreview_status
Review finding:
POST /compliance-findings/{finding_id}/reviews
Workflow API
Workflow Templates
GET /workflow-templatesPOST /workflow-templatesGET /workflow-templates/{id}PATCH /workflow-templates/{id}POST /workflow-templates/{id}/archive
Start Workflow
POST /proposals/{proposal_id}/workflows
Example request:
{ "workflow_template_id": "uuid", "name": "Standard Government IT Proposal Workflow"}
Tasks
GET /tasksGET /tasks/{task_id}POST /workflows/{workflow_id}/tasksPATCH /tasks/{task_id}POST /tasks/{task_id}/completePOST /tasks/{task_id}/reassign
Task filters:
statuspriorityowner_user_idproposal_iddue_beforeoverdue
Approvals API
Create approval request:
POST /approvals
Example request:
{ "approval_type": "final_proposal", "resource_type": "proposal", "resource_id": "uuid", "assigned_to_user_id": "uuid", "message": "Please approve the final proposal for export."}
Decide:
POST /approvals/{approval_id}/decisions
Example:
{ "decision": "approved", "reason": "All mandatory requirements are covered."}
The decision actor is derived from authentication.
Notifications API
GET /notificationsPOST /notifications/{id}/readPOST /notifications/read-allPOST /notifications/{id}/dismiss
Notifications should not expose confidential content beyond the recipient’s permissions.
Export API
Create export:
POST /proposals/{proposal_id}/exports
Example request:
{ "export_type": "docx", "template_key": "standard_it_services", "citation_mode": "footnotes", "include_appendices": true, "appendix_types": [ "consultant_cvs", "certifications", "case_studies" ]}
Response:
202 Accepted
Get export:
GET /exports/{export_id}
Download:
GET /exports/{export_id}/download
The download endpoint should verify:
- Organization
- User permission
- Export status
- Retention state
AI Execution API Boundary
Most product users should not interact with raw AI executions directly.
Product endpoints should initiate domain actions such as:
- Analyze opportunity
- Extract requirements
- Generate outline
- Draft section
- Validate proposal
Administrative or diagnostic access may use:
GET /ai-executionsGET /ai-executions/{id}
Responses should include safe metadata:
{ "id": "uuid", "feature": "proposal_section_draft", "status": "completed", "provider": "google", "model": "configured-model-name", "prompt_key": "proposal-section-draft", "prompt_version": "2", "latency_ms": 5240, "input_tokens": 18240, "output_tokens": 1340, "estimated_cost": "0.12", "currency": "USD", "created_at": "..."}
It should not expose:
- API keys
- Full hidden instructions
- Unauthorized source content
- Sensitive provider diagnostics
AI Feedback API
POST /ai-executions/{id}/feedback
Example request:
{ "feedback_type": "edited", "rating": 4, "comment": "Useful draft, but technical assumptions required correction."}
Usage API
Authorized users may access organization usage.
GET /usage/ai
Filters:
date_fromdate_tofeaturemodeluser_id
Example response:
{ "summary": { "request_count": 184, "input_tokens": 2145000, "output_tokens": 182000, "estimated_cost": "87.42", "currency": "USD" }, "breakdown": []}
Access should be limited to owners, administrators, or authorized financial roles.
Audit API
Audit events are sensitive.
GET /audit-eventsGET /audit-events/{id}
Filters may include:
actionactor_user_idresource_typeresource_iddate_fromdate_tocorrelation_id
Responses should redact:
- Secrets
- Password material
- Raw tokens
- Excessive document content
- Sensitive provider payloads
Health and Operations API
Public or infrastructure endpoints should remain separate from normal business APIs.
GET /healthGET /readyGET /version
/health
Confirms the process is running.
/ready
Confirms required dependencies are available.
/version
Returns release metadata without exposing sensitive configuration.
Example:
{ "service": "bidradar-api", "version": "0.1.0", "commit": "short-sha", "environment": "staging"}
API Schema Separation
Pydantic schemas should be separated by responsibility.
Example conceptual categories:
OpportunityCreateOpportunityUpdateOpportunitySummaryOpportunityDetailOpportunityListResponse
Avoid using one schema for:
- Create
- Update
- Database model
- Response
- Internal service input
Different contexts have different security and validation requirements.
Create Versus Update Contracts
Create schemas should include only client-settable fields.
Update schemas should:
- Make fields optional
- Exclude immutable fields
- Support concurrency
- Validate state transitions
Response schemas may include:
- IDs
- Timestamps
- Derived state
- Relationship summaries
- Permissions
Permission Hints
The backend may include UI-support metadata.
Example:
{ "permissions": { "can_edit": true, "can_delete": false, "can_request_analysis": true, "can_approve": false }}
These hints improve the UI.
They do not replace backend authorization.
Status Transition Contracts
Clients should not freely patch statuses when transitions carry business meaning.
Unsafe:
PATCH /opportunities/{id}{ "status": "submitted"}
Safer:
POST /proposals/{id}/mark-submitted
or a documented transition endpoint.
This allows the service layer to validate:
- Required approvals
- Export status
- Submission metadata
- Current state
- Actor permissions
Bulk Operations
Bulk endpoints may be useful later.
Examples:
POST /opportunities/bulk-archivePOST /requirements/bulk-reviewPOST /tasks/bulk-reassign
Bulk operations must:
- Limit batch size
- Validate every item
- Report partial failures clearly
- Preserve tenant scope
- Use asynchronous processing for large operations
They are not required in the initial MVP unless a user journey clearly requires them.
Webhook Principles
Future integrations may receive event notifications.
Potential webhook events include:
opportunity.createddocument.processing_completedrequirement.extraction_completedproposal.approvedexport.completed
Webhook design should include:
- Signed requests
- Event IDs
- Event version
- Retry behavior
- Idempotency
- Delivery history
- Secret rotation
Production webhooks are deferred until integration phases.
Internal Events Versus Public Webhooks
Internal domain events coordinate BidRadar modules.
Public webhooks notify external systems.
These are not the same contract.
Internal event schemas may evolve more quickly.
Public webhook schemas require stronger compatibility guarantees.
Rate Limiting
Rate limits should consider:
- IP address
- User
- Organization
- Endpoint
- AI cost
- File size
- External integration quotas
Example headers:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
AI operations may use budget limits rather than ordinary request counts alone.
Usage-Limit Errors
Example:
{ "error": { "code": "ai_usage_limit_exceeded", "message": "The organization has reached its monthly AI usage limit.", "request_id": "req_123", "details": { "period": "2027-03", "limit_type": "estimated_cost" } }}
Security Requirements for API Contracts
The API must:
- Require HTTPS in production.
- Validate bearer tokens.
- Validate organization membership.
- Enforce permissions server-side.
- Validate all request bodies.
- Sanitize file names.
- Restrict upload size and media type.
- Avoid mass-assignment vulnerabilities.
- Avoid returning internal database fields.
- Avoid exposing secrets.
- Redact sensitive logs.
- Apply rate limits.
- Record sensitive actions.
- Enforce tenant scope during search and retrieval.
Mass-Assignment Prevention
Generated code should never automatically map all JSON fields to ORM objects.
Clients must not be able to set:
organization_idcreated_by_user_idapproved_by_user_idstatuswhere controlled by workflowcurrent_version_idai_execution_idstorage_keychecksum_sha256- Audit fields
Create and update schemas must explicitly permit fields.
Search Security
Knowledge and semantic-search endpoints must enforce access before returning results.
The client must not be allowed to bypass filtering through:
- Direct chunk IDs
- Document IDs
- Customer metadata
- Security classification
- Archived-version references
Every returned search result must be authorized.
Prompt-Injection Security
Document content is untrusted.
The API should not expose an endpoint that accepts arbitrary instructions and automatically grants unrestricted tool access.
AI action requests should use controlled fields such as:
{ "generation_profile": "evidence_backed_standard", "instructions": "Emphasize service continuity."}
User instructions are treated as bounded content, not system policy.
OpenAPI Documentation
FastAPI can generate OpenAPI documentation automatically.
The API specification should still be written first.
Generated OpenAPI must include:
- Endpoint summary
- Description
- Authentication requirements
- Request schema
- Response schema
- Error responses
- Tags
- Deprecation state
- Examples where useful
Automatic documentation quality depends on well-designed routers and Pydantic schemas.
API Tags
Suggested tags include:
AuthenticationOrganizationsOpportunitiesTender DocumentsRequirementsAnalysisScoringKnowledgeProposalsComplianceWorkflowsApprovalsNotificationsExportsJobsUsageAuditOperations
Contract Testing
The API implementation should later include:
- Schema tests
- Authentication tests
- Permission tests
- Tenant-isolation tests
- Pagination tests
- Filtering tests
- Error-format tests
- Concurrency tests
- Idempotency tests
- File-upload tests
- Background-job tests
- OpenAPI snapshot or compatibility tests
Frontend Contract Generation
The React frontend should not manually redefine every backend type.
Possible approaches include:
- Generating TypeScript types from OpenAPI
- Maintaining shared schema packages
- Using a typed API client generator
The initial implementation can generate TypeScript contracts from the FastAPI OpenAPI document.
This reduces drift between:
- Pydantic schemas
- API clients
- Form types
- Query hooks
Mock API Strategy
Before the real FastAPI backend is complete, Google AI Studio may generate mock frontend data.
Mock contracts must match the API specification.
Mock data should not invent an alternate schema.
For example, a mock opportunity should use:
{ "id": "uuid", "title": "Cloud Migration Services", "status": "reviewing", "submission_deadline": "2027-04-15T12:00:00Z", "currency": "USD"}
The mock layer should be replaceable by the real API client.
API Evolution Strategy
Each contract change should answer:
- Is this breaking?
- Which clients are affected?
- Is a migration period required?
- Must old fields remain temporarily?
- Does the OpenAPI document change?
- Do frontend types need regeneration?
- Do integration tests need updates?
API changes should be reviewed like database migrations.
REST API Resource Map
The high-level endpoint map is:
/api/v1├── /auth├── /organizations├── /opportunities├── /buyers├── /tender-sources├── /tender-imports├── /documents├── /document-versions├── /document-extractions├── /requirements├── /analyses├── /opportunity-scores├── /bid-decisions├── /knowledge-documents├── /knowledge-versions├── /knowledge-search├── /proposals├── /proposal-sections├── /comments├── /reviews├── /compliance-runs├── /compliance-findings├── /workflow-templates├── /workflows├── /tasks├── /approvals├── /notifications├── /exports├── /jobs├── /ai-executions├── /usage└── /audit-events
Not all endpoints will be implemented immediately.
The contract document distinguishes MVP endpoints from future endpoints.
MVP API Scope
The initial MVP API should prioritize one complete vertical workflow.
Authentication and Organization
- Register
- Login
- Current user
- Create organization
- List memberships
- Invite user
Opportunity
- Create
- List
- Get
- Update
Tender Documents
- Upload
- List
- Get processing status
- Download
Analysis
- Start summary
- Start requirement extraction
- Get job
- Get results
Scoring
- Start score
- Get score
- Create human Bid decision
Knowledge
- Upload
- List
- Approve
- Search
Proposal
- Create
- Generate outline
- List sections
- Generate section draft
- Save human edit
- Approve section
Compliance
- Start validation
- List findings
Export
- Request DOCX
- Get export status
- Download
Deferred API Scope
Deferred endpoints include:
- Live procurement-portal submissions
- Advanced CRM synchronization
- Microsoft Graph integrations
- Slack and Teams external notification delivery
- Real-time co-editing
- Predictive analytics
- External customer APIs
- Public webhooks
- Fine-grained custom permission management
- Autonomous agent execution APIs
API Risks
Risk 1 — Overly Generic CRUD
Problem
Business rules are bypassed through unrestricted patch endpoints.
Mitigation
Use explicit action endpoints for approvals, processing, generation, and lifecycle transitions.
Risk 2 — Inconsistent Contracts
Problem
Each generated feature uses its own error and pagination format.
Mitigation
Define shared API conventions before implementation.
Risk 3 — Tenant IDs Trusted from Clients
Problem
Attackers may attempt cross-tenant access by changing organization IDs.
Mitigation
Verify membership, resource ownership, and active organization on every request.
Risk 4 — Long Requests Time Out
Problem
AI and document processing run synchronously.
Mitigation
Use 202 Accepted and durable background-job resources.
Risk 5 — Lost Collaborative Edits
Problem
One user overwrites another user’s proposal update.
Mitigation
Use version tokens and optimistic concurrency.
Risk 6 — Internal AI Details Exposed
Problem
Prompts, provider errors, or confidential context reach the browser.
Mitigation
Return safe summaries and retain sensitive diagnostics server-side.
Risk 7 — Contract Drift
Problem
React types, Pydantic schemas, and documentation diverge.
Mitigation
Generate OpenAPI, produce typed clients, and add contract tests.
Recommended API Specification Document
Create:
docs/└── api-specification.md
Recommended structure:
# BidRadar REST API and Application Contracts## Document Control## Purpose## API Principles## Base URL and Versioning## Authentication## Organization Context## Authorization## Naming and Data Formats## Standard Responses## Pagination## Filtering## Sorting## Search## Error Contract## Idempotency## Concurrency## Background Jobs## File Uploads## Organizations## Opportunities## Documents## Requirements## Analyses## Opportunity Scoring## Bid Decisions## Knowledge## Semantic Search## Proposals## Proposal Sections## Collaboration## Compliance## Workflows## Tasks## Approvals## Notifications## Exports## AI Execution Metadata## Usage## Audit## Operations## Rate Limits## Security## OpenAPI## Contract Testing## MVP Endpoints## Deferred Endpoints## Risks## Open Questions
Open API Questions
Several decisions remain open.
- Should organization context use a header, path prefix, or token claim?
- Should refresh tokens use secure cookies or response bodies?
- Which collections should use cursor pagination from the start?
- Should monetary values always be returned as strings?
- Should proposal content use Markdown, HTML, or a structured editor format?
- Which operations require idempotency keys?
- Should optimistic concurrency use ETags or explicit version fields?
- Should file uploads use backend proxying or direct-to-storage sessions first?
- Which nested resources should support
includeexpansion? - Should knowledge search use REST, GraphQL, or a specialized search endpoint?
- Which API responses may contain AI confidence values?
- Which internal prompt metadata is safe to expose to administrators?
- Which audit-event fields should be redacted?
- Should the API support users belonging to multiple active organizations simultaneously?
- Which endpoints require stricter rate limits?
- Should OpenAPI clients be generated during CI?
These questions should remain documented until implementation decisions are approved.
Google AI Studio API Planning Prompt
Use this prompt before generating the formal specification.
You are helping design the REST API and application contracts for BidRadar.BidRadar is a secure, multi-tenant AI Tender Intelligence and Proposal Automation SaaS platform for IT service providers.Do not generate FastAPI code.Do not generate React code.Do not generate Pydantic models.Do not generate SQLAlchemy models.Read these documents if available:- docs/project-vision.md- docs/product-requirements.md- docs/architecture.md- docs/database-schema.md- docs/google-ai-studio-workflow.mdYour task is to plan the REST API specification.Provide:1. API design principles.2. Base URL and versioning strategy.3. Authentication contracts.4. Organization-context strategy.5. Authorization behavior.6. JSON naming conventions.7. Identifier, date, timestamp, and monetary formats.8. Standard single-resource responses.9. Collection and pagination contracts.10. Filtering, sorting, and search conventions.11. Error-response format.12. Validation-error format.13. Request-correlation strategy.14. Idempotency rules.15. Optimistic-concurrency rules.16. Background-job contracts.17. File-upload and download contracts.18. Organization endpoints.19. Opportunity endpoints.20. Tender-document endpoints.21. Requirement endpoints.22. Tender-analysis endpoints.23. Scoring and Bid/No-Bid endpoints.24. Knowledge-document endpoints.25. Semantic-search endpoint.26. Proposal endpoints.27. Proposal-section versioning endpoints.28. Comment and review endpoints.29. Compliance endpoints.30. Workflow and task endpoints.31. Approval endpoints.32. Notification endpoints.33. Export endpoints.34. AI execution and feedback boundaries.35. Usage endpoints.36. Audit endpoints.37. Health and readiness endpoints.38. Rate-limit behavior.39. Security requirements.40. OpenAPI and contract-testing strategy.41. MVP endpoint set.42. Deferred endpoints.43. Risks.44. Open questions.Constraints:- Use resource-oriented REST.- Use /api/v1.- Use JSON over HTTPS.- Keep tenant context explicit and verified.- Do not trust organization_id from request bodies.- Long-running operations must return 202 and a job resource.- Use stable machine-readable error codes.- Use explicit business-action endpoints for approvals and state transitions.- Use optimistic concurrency for collaborative and versioned resources.- Keep Gemini prompts and secrets server-side.- Do not expose SQLAlchemy models directly.- Do not generate code.
Google AI Studio API Specification Prompt
After reviewing the plan, use:
Create the formal BidRadar REST API and Application Contracts document.Write the result as Markdown suitable for:docs/api-specification.mdRead and follow:- docs/project-vision.md- docs/product-requirements.md- docs/architecture.md- docs/database-schema.md- docs/google-ai-studio-workflow.mdInclude:1. Document control2. Purpose and scope3. API design principles4. Base URLs5. API versioning6. Content types7. Naming conventions8. UUID format9. Date and timestamp format10. Monetary-value format11. Authentication endpoints12. Session and token contracts13. Current-user contract14. Organization-context strategy15. Organization and membership endpoints16. Authorization response behavior17. Standard resource metadata18. Collection responses19. Offset pagination20. Cursor pagination21. Filtering22. Sorting23. Free-text search24. Expansion rules25. Standard success responses26. Standard error responses27. Validation-error responses28. HTTP status-code usage29. Request and correlation IDs30. Idempotency31. Optimistic concurrency32. Soft deletion and archive actions33. Background-job contracts34. Job cancellation35. File-upload contracts36. File-download authorization37. Opportunity endpoints38. Tender-document endpoints39. Document-extraction endpoints40. Requirement endpoints41. Tender-analysis endpoints42. Opportunity-scoring endpoints43. Human Bid/No-Bid endpoints44. Knowledge-document endpoints45. Knowledge-version approval46. Semantic and hybrid-search endpoints47. Proposal endpoints48. Proposal-outline generation49. Proposal-section generation and versioning50. Section approval and locking51. Comments and reviews52. Compliance endpoints53. Workflow-template endpoints54. Workflow and task endpoints55. Approval endpoints56. Notification endpoints57. Export endpoints58. AI execution metadata59. AI feedback60. Usage reporting61. Audit access62. Health, readiness, and version endpoints63. Rate limiting64. Security requirements65. Prompt-injection boundaries66. OpenAPI documentation67. Generated TypeScript client strategy68. Contract testing69. Mock API requirements70. API evolution and deprecation71. MVP endpoint scope72. Deferred endpoint scope73. Risks and mitigations74. Open questionsFor every major endpoint:- State the HTTP method.- State the route.- Explain the purpose.- Describe required permission.- Describe important request fields.- Describe important response fields.- List likely error responses.- State whether the operation is synchronous or asynchronous.Constraints:- Use /api/v1.- Use snake_case JSON.- Use UUID identifiers.- Use ISO 8601 timestamps.- Use decimal-safe monetary contracts with explicit currency.- Use tenant-aware authorization.- Derive organization ownership server-side.- Use 202 Accepted for long-running operations.- Return durable job resources.- Use explicit approval and lifecycle action endpoints.- Use versioned proposal and requirement contracts.- Preserve AI evidence and citations.- Keep provider secrets and hidden prompts server-side.- Do not generate code.- Do not redefine the database schema.
API Review Prompt
After generating the specification, use:
Review the BidRadar REST API and Application Contracts document.Do not rewrite it yet.Do not generate code.Evaluate:1. Alignment with the Product Requirements Document.2. Alignment with the architecture.3. Alignment with the database schema.4. Inconsistent naming.5. Missing tenant context.6. Unsafe organization_id handling.7. Missing authorization requirements.8. Missing error contracts.9. Inconsistent pagination.10. Unbounded search or list endpoints.11. Long-running synchronous operations.12. Missing durable job resources.13. Missing idempotency.14. Missing optimistic concurrency.15. Unsafe generic status updates.16. Missing explicit approval actions.17. Missing proposal versioning.18. Missing requirement versioning.19. Missing file validation.20. Missing AI traceability.21. Exposure of secrets or hidden prompts.22. Missing rate limits.23. Missing audit boundaries.24. Missing OpenAPI or contract testing.25. Endpoints that should be deferred.26. Contradictory request or response fields.27. Open questions treated as final decisions.Classify each finding as:- Critical- High- Medium- LowFor every finding:- Identify the endpoint or section.- Explain the risk.- Recommend a specific correction.
Manual API Review Checklist
Consistency
- Does every endpoint use the same naming convention?
- Are dates and money represented consistently?
- Are collection responses standardized?
- Are error responses standardized?
Security
- Is organization context verified?
- Can clients set protected ownership fields?
- Are authorization requirements documented?
- Are file downloads protected?
- Are AI secrets hidden?
Asynchronous Work
- Do long operations return
202 Accepted? - Are job resources durable?
- Can users inspect failures?
- Are retries and cancellation considered?
Versioning
- Are proposal sections versioned?
- Are requirements versioned?
- Is concurrency protected?
- Are approvals tied to exact versions?
AI
- Are AI operations requested through domain endpoints?
- Is prompt metadata controlled?
- Are citations preserved?
- Are usage and feedback supported?
Frontend
- Can TypeScript types be generated?
- Can TanStack Query hooks map cleanly to resources?
- Can mock data follow the same contracts?
- Are loading and error states supported?
Validation Checklist
Before continuing to Part 7, verify that:
docs/api-specification.mdexists.- Document version and status are included.
/api/v1is defined.- JSON naming conventions are defined.
- UUID contracts are defined.
- Date and timestamp formats are defined.
- Monetary-value formats are defined.
- Authentication contracts are documented.
- Organization context is explicit.
- Membership validation is mandatory.
- Authorization behavior is documented.
- Standard resource metadata is defined.
- Pagination is defined.
- Filtering is defined.
- Sorting is defined.
- Search is defined.
- Error responses are standardized.
- Validation errors are standardized.
- HTTP status codes are documented.
- Request IDs are included.
- Idempotency is documented.
- Optimistic concurrency is documented.
- Long-running operations use job resources.
- Job statuses are defined.
- File-upload contracts are documented.
- File-download authorization is documented.
- Opportunity endpoints are documented.
- Tender-document endpoints are documented.
- Requirement endpoints are documented.
- Analysis endpoints are documented.
- Scoring endpoints are documented.
- Human Bid/No-Bid endpoints are documented.
- Knowledge endpoints are documented.
- Semantic-search contracts are documented.
- Proposal endpoints are documented.
- Proposal-section versioning is documented.
- Approval endpoints are explicit.
- Compliance endpoints are documented.
- Workflow and task endpoints are documented.
- Export endpoints are documented.
- AI execution exposure is limited.
- Usage endpoints are access-controlled.
- Audit endpoints are restricted.
- Health and readiness endpoints are documented.
- Rate limits are acknowledged.
- OpenAPI generation is planned.
- Contract testing is planned.
- MVP endpoints are separated from deferred endpoints.
- No FastAPI code has been generated.
- No React API client has been generated.
- No Pydantic schemas have been generated.
Definition of Done
Part 6 is complete when:
- The frontend and backend can be generated against one stable contract.
- Tenant context is unambiguous.
- Business actions are explicit.
- Long-running work uses asynchronous contracts.
- Error handling is predictable.
- Collaborative updates are concurrency-safe.
- File and AI operations are secure.
- Proposal and requirement history is preserved.
- The API supports the complete MVP workflow.
- The OpenAPI document can later generate frontend types.
- The team approves the specification as the basis for implementation.
Recommended Git Commit
docs(api): define BidRadar REST API and application contracts
A later correction may use:
docs(api): strengthen tenant context and asynchronous job contracts
What We Built
In this article, we designed the complete application contract for BidRadar.
The specification now defines:
- API versioning
- Authentication
- Organization context
- Authorization
- Resource naming
- JSON formats
- Pagination
- Filtering
- Sorting
- Search
- Errors
- Request IDs
- Idempotency
- Concurrency
- Background jobs
- File upload and download
- Opportunities
- Tender documents
- Requirements
- Tender analyses
- Opportunity scoring
- Human Bid/No-Bid decisions
- Knowledge management
- Semantic search
- Proposal generation
- Proposal versioning
- Collaboration
- Compliance
- Workflows
- Tasks
- Approvals
- Notifications
- Exports
- AI usage
- Audit access
- Health endpoints
- Rate limits
- OpenAPI and contract testing
No backend or frontend code has been generated yet.
The product requirements, architecture, database schema, and API contracts now form a coherent technical foundation.
Next Article
Part 7 — Establishing the BidRadar Design System and User Experience
In the next article, we will define how BidRadar should look and behave before Google AI Studio generates the initial application.
We will establish:
- Brand identity
- BidRadar colors
- Typography
- Spacing
- Layout
- Navigation
- Dashboard structure
- Cards
- Tables
- Forms
- Status badges
- Charts
- Empty states
- Loading states
- Error states
- Responsive design
- Accessibility
- Interaction patterns
- Proposal-editor layout
- Tender-analysis workspace
- Knowledge-search experience
- Workflow dashboard
- Administrative interfaces
We will create:
docs/└── design-system.md
This document will ensure that Google AI Studio generates one coherent enterprise SaaS application rather than a collection of unrelated screens.