Skip to main content

Proposals API

Manage data modification proposals.

Endpoints

POST /proposals

POST Create a proposal.

curl -X POST "https://api.ofself.ai/api/v1/proposals" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{
"title": "Extract Entities from Chunk 0",
"description": "Found 23 entities...",
"type": "CREATE_NODE",
"graph_view": "identity",
"raw_data": { "source": "my-app", "original_text": "..." },
"canonical_data": { "entities": [ /* ... */ ] },
"tags": ["work", "imported"]
}'

Notes:

  • Creating proposals is intended for third-party apps (API key auth).
  • Users typically approve/reject proposals using JWT auth from the dashboard.

Common Proposal Types (type):

TypeDescription
CREATE_NODECreate new nodes
UPDATE_NODEModify existing nodes
DELETE_NODERemove nodes
MERGE_NODESCombine multiple nodes
CREATE_RELATIONSHIPAdd connections

GET /proposals

GET List proposals.

curl -X GET "https://api.ofself.ai/api/v1/proposals?status=PENDING&page=1&per_page=50" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"

Query Parameters:

ParameterTypeDescription
statusstringPENDING, READY_FOR_APPROVAL, APPROVED, REJECTED, APPLIED, FAILED
graph_viewstringneutral or identity
pageintegerPage number (optional)
per_pageintegerItems per page (optional)
limitintegerLimit (optional, alternative pagination)
offsetintegerOffset (optional, alternative pagination)

GET /proposals/:proposal_id

GET Get proposal details.


PATCH /proposals/:proposal_id

PATCH Update a proposal (for agent enrichment).

curl -X PATCH "https://api.ofself.ai/api/v1/proposals/prop_abc" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{
"canonical_data": {"entities": [...]},
"tags": ["new_tag"],
"entity_tags": {},
"reasoning_metadata": {},
"status": "READY_FOR_APPROVAL"
}'

Request Body:

FieldTypeDescription
canonical_dataobjectStructured data to create
tagsarrayTag names
entity_tagsobjectPer-entity tag mappings
reasoning_metadataobjectAgent reasoning info
actionsarrayActions to execute
statusstringUpdate status

POST /proposals/:proposal_id/approve

POST Approve a proposal.

First-Party Only

This endpoint is called by the user on app.ofself.ai to approve proposals. Third-party apps cannot call this endpoint - they create proposals and wait for user approval via webhooks or polling.

Response: Marks proposal APPROVED (optionally with granular approvals).

{
"status": "APPROVED",
"message": "Proposal approved successfully"
}

POST /proposals/:proposal_id/reject

POST Reject a proposal.

First-Party Only

This endpoint is called by the user on app.ofself.ai to reject proposals. Third-party apps cannot call this endpoint.


POST /proposals/:proposal_id/apply

POST Execute an approved proposal (creates nodes/relationships).

curl -X POST "https://api.ofself.ai/api/v1/proposals/prop_abc/apply" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"

Response: 200 OK

{
"status": "APPLIED",
"nodes_created": 3,
"relationships_created": 2,
"tags_created": 1,
"errors": []
}

Note: Proposal must be in APPROVED status before applying.


DELETE /proposals/:proposal_id

DELETE Delete a proposal.

curl -X DELETE "https://api.ofself.ai/api/v1/proposals/prop_abc" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"

Response: 200 OK

{
"message": "Proposal deleted successfully",
"id": "prop_abc"
}

POST /proposals/subscribe

POST Subscribe to proposal events (for apps).

curl -X POST "https://api.ofself.ai/api/v1/proposals/subscribe" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{
"event_types": ["created", "ready", "approved", "rejected", "applied", "failed"],
"webhook_url": "https://myapp.com/webhooks/proposals"
}'

GET /proposals/events

GET Poll proposal events (fallback if you don’t use webhooks).

curl -X GET "https://api.ofself.ai/api/v1/proposals/events?limit=50" \
-H "X-API-Key: your-key" \
-H "X-User-ID: user-123"

Proposal Lifecycle

Created (PENDING) → Ready (READY_FOR_APPROVAL) → Approved (APPROVED) → Applied (APPLIED)
↘ Rejected (REJECTED)