Your First API Call
Let's make your first API call to OfSelf! We'll create a simple note in a user's vault.
Prerequisites
- Registered app with API key
- A user who has authorized your app (for testing, use your own account)
Option 1: Using cURL
# Create a proposal to add a node
curl -X POST "https://api.ofself.ai/api/v1/proposals" \
-H "X-API-Key: ofs_key_xxxxxxxxxxxxx" \
-H "X-User-ID: user-123" \
-H "Content-Type: application/json" \
-d '{
"proposal_type": "create_node",
"canonical_data": {
"entities": [{
"title": "Hello OfSelf!",
"value": "This is my first note created via the API.",
"node_type": "note"
}]
}
}'
Response:
{
"id": "prop_a1b2c3d4",
"status": "pending",
"proposal_type": "create_node",
"created_at": "2024-01-15T10:30:00Z"
}
Proposals vs Direct Creation
By default, apps create proposals that users approve. This gives users control over what enters their data vault. Some apps with higher trust levels can create nodes directly.
Option 2: Using Python SDK
Install the SDK
pip install ofself
Create a Client
from ofself import OfSelfClient
# Initialize with your API key
client = OfSelfClient(api_key="ofs_key_xxxxxxxxxxxxx")
Create a Proposal
# Create a proposal to add a note
proposal = client.proposals.create(
user_id="user-123",
proposal_type="create_node",
canonical_data={
"entities": [{
"title": "Hello OfSelf!",
"value": "This is my first note created via the API.",
"node_type": "note"
}]
}
)
print(f"Proposal created: {proposal['id']}")
print(f"Status: {proposal['status']}")
List Existing Nodes
# List user's nodes
result = client.nodes.list(user_id="user-123", per_page=10)
print(f"Found {result['total']} nodes")
for node in result['items']:
print(f" - {node['title']} ({node['node_type']})")
Option 3: Using JavaScript SDK
Install the SDK
npm install @ofself/sdk
Create a Client
import { OfSelfClient } from '@ofself/sdk';
const client = new OfSelfClient({
apiKey: 'ofs_key_xxxxxxxxxxxxx'
});
Create a Proposal
// Create a proposal to add a note
const proposal = await client.proposals.create({
userId: 'user-123',
proposalType: 'create_node',
canonicalData: {
entities: [{
title: 'Hello OfSelf!',
value: 'This is my first note created via the API.',
nodeType: 'note'
}]
}
});
console.log(`Proposal created: ${proposal.id}`);
console.log(`Status: ${proposal.status}`);
List Existing Nodes
// List user's nodes
const { items, total } = await client.nodes.list({
userId: 'user-123',
perPage: 10
});
console.log(`Found ${total} nodes`);
items.forEach(node => {
console.log(` - ${node.title} (${node.nodeType})`);
});
Understanding the Response
When you create a proposal, you get back:
| Field | Description |
|---|---|
id | Unique proposal identifier |
status | pending, approved, or rejected |
proposal_type | What kind of change is proposed |
canonical_data | The structured data you submitted |
created_at | When the proposal was created |
What Happens Next?
- User sees proposal in their OfSelf dashboard
- User reviews the proposed changes
- User approves or rejects
- If approved, the node is created in their vault
- Your app receives webhook (if configured) notifying of the change
Error Handling
Always handle potential errors:
from ofself import OfSelfClient
from ofself.exceptions import (
AuthenticationError,
PermissionDenied,
NotFoundError,
RateLimitError
)
client = OfSelfClient(api_key="your-key")
try:
nodes = client.nodes.list(user_id="user-123")
except AuthenticationError:
print("Invalid API key")
except PermissionDenied:
print("User hasn't authorized your app")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except Exception as e:
print(f"Unexpected error: {e}")
Next Steps
Now that you've made your first API call:
- Learn about Nodes - The core data structure
- Understand Proposals - How apps modify user data
- Set up Webhooks - Get real-time notifications