# Proposals API The Proposals API provides endpoints for managing symbiosis proposals between organizations. Proposals represent requests for resource exchange or collaboration opportunities. ## Base URL ``` https://api.turash.com/api/v1 ``` ## Endpoints ### Get All Proposals Retrieve all proposals with optional filtering. **Endpoint:** `GET /api/v1/proposals` **Query Parameters:** - `status` (optional): Filter by proposal status (`pending`, `accepted`, `rejected`) - `from_org` (optional): Filter by proposing organization ID - `to_org` (optional): Filter by target organization ID - `limit` (optional): Maximum number of results (default: 50) - `offset` (optional): Pagination offset (default: 0) **Response:** ```json [ { "id": "proposal-123", "from_org_id": "org-456", "to_org_id": "org-789", "resource_id": "resource-101", "resource_type": "input", "resource_name": "Organic Waste", "message": "We can provide organic waste for your composting needs", "status": "pending", "created_at": "2024-01-15T10:30:00Z" } ] ``` ### Get Proposal by ID Retrieve a specific proposal by its ID. **Endpoint:** `GET /api/v1/proposals/{id}` **Path Parameters:** - `id`: Proposal ID **Response:** ```json { "id": "proposal-123", "from_org_id": "org-456", "to_org_id": "org-789", "resource_id": "resource-101", "resource_type": "input", "resource_name": "Organic Waste", "message": "We can provide organic waste for your composting needs", "status": "pending", "created_at": "2024-01-15T10:30:00Z" } ``` **Error Responses:** - `404 Not Found` - Proposal not found ### Get Proposals by Organization Retrieve all proposals where an organization is either the sender or receiver. **Endpoint:** `GET /api/v1/organizations/{id}/proposals` **Path Parameters:** - `id`: Organization ID **Response:** ```json { "incoming": [ { "id": "proposal-123", "from_org_id": "org-456", "to_org_id": "org-789", "resource_id": "resource-101", "resource_type": "input", "resource_name": "Organic Waste", "message": "We can provide organic waste for your composting needs", "status": "pending", "created_at": "2024-01-15T10:30:00Z" } ], "outgoing": [ { "id": "proposal-124", "from_org_id": "org-789", "to_org_id": "org-456", "resource_id": "resource-102", "resource_type": "output", "resource_name": "Heat Energy", "message": "Interested in your heat recovery system", "status": "accepted", "created_at": "2024-01-16T14:20:00Z" } ] } ``` ### Create Proposal Create a new symbiosis proposal. **Endpoint:** `POST /api/v1/proposals` **Request Body:** ```json { "from_org_id": "org-456", "to_org_id": "org-789", "resource_id": "resource-101", "resource_type": "input", "resource_name": "Organic Waste", "message": "We can provide organic waste for your composting needs" } ``` **Required Fields:** - `from_org_id`: ID of the proposing organization - `to_org_id`: ID of the target organization - `resource_id`: ID of the resource flow being proposed - `resource_type`: Direction of the resource flow (`input` or `output`) - `resource_name`: Human-readable name of the resource **Optional Fields:** - `message`: Additional message or proposal details **Response:** ```json { "id": "proposal-123", "from_org_id": "org-456", "to_org_id": "org-789", "resource_id": "resource-101", "resource_type": "input", "resource_name": "Organic Waste", "message": "We can provide organic waste for your composting needs", "status": "pending", "created_at": "2024-01-15T10:30:00Z" } ``` **Error Responses:** - `400 Bad Request` - Invalid request data - `404 Not Found` - Organization or resource not found ### Update Proposal Status Update the status of an existing proposal. **Endpoint:** `POST /api/v1/proposals/{id}/status` **Path Parameters:** - `id`: Proposal ID **Request Body:** ```json { "status": "accepted" } ``` **Valid Status Values:** - `pending` - Initial status, awaiting response - `accepted` - Proposal accepted by target organization - `rejected` - Proposal rejected by target organization **Response:** ```json { "message": "Proposal status updated successfully" } ``` **Error Responses:** - `400 Bad Request` - Invalid status value - `404 Not Found` - Proposal not found ## Data Types ### Proposal Status ```typescript type ProposalStatus = 'pending' | 'accepted' | 'rejected'; ``` ### Proposal Object ```typescript interface Proposal { id: string; from_org_id: string; to_org_id: string; resource_id: string; resource_type: 'input' | 'output'; resource_name: string; message?: string; status: ProposalStatus; created_at: string; } ``` ## Business Rules ### Proposal Lifecycle 1. **Creation**: Proposals are created with `pending` status 2. **Response**: Target organization can accept or reject the proposal 3. **Final State**: Once accepted or rejected, status cannot be changed ### Validation Rules - Organizations cannot propose to themselves - Resource must exist and be owned by the proposing organization - Resource type must match the direction being proposed - Message length limited to 500 characters ### Permissions Currently, all proposal operations are publicly accessible. Future implementations will include: - Authentication requirements - Authorization based on organization membership - Proposal creation limits per organization ## Error Codes | Code | Description | |------|-------------| | `VALIDATION_ERROR` | Request data validation failed | | `PROPOSAL_NOT_FOUND` | Specified proposal does not exist | | `ORGANIZATION_NOT_FOUND` | Specified organization does not exist | | `RESOURCE_NOT_FOUND` | Specified resource does not exist | | `INVALID_STATUS_TRANSITION` | Attempted invalid status change | | `SELF_PROPOSAL_ERROR` | Organization cannot propose to itself | ## Rate Limits - Create Proposal: 10 per hour per organization - Update Status: 50 per hour per organization - Get Operations: 100 per hour per IP ## WebSocket Events The API emits WebSocket events for real-time proposal updates: - `proposal_created`: New proposal submitted - `proposal_status_changed`: Proposal status updated **Event Payload:** ```json { "type": "proposal_status_changed", "proposal_id": "proposal-123", "old_status": "pending", "new_status": "accepted", "updated_by": "org-789", "timestamp": "2024-01-15T10:35:00Z" } ```