Authentication
Third-party apps authenticate using API Keys with user authorization.
Third-party developers must use API Key + X-User-ID authentication. User JWT authentication (login with email/password) is exclusively for app.ofself.ai and is NOT available to third-party apps.
The Complete Flow
Here's the end-to-end flow from registering your app to making API calls:
STEP 1: Register your app (Developer Dashboard)
→ You receive: client_id + api_key
STEP 2: Direct user to authorize your app
→ URL: https://api.ofself.ai/api/v1/authorize?client_id=<your_client_id>&redirect_uri=<your_callback_url>
→ User logs in, selects an exposure profile, approves
STEP 3: Receive callback with user_id
→ Your callback URL is called:
https://yourapp.com/callback?code=success&client_id=tp_...&user_id=<uuid>
→ Store the user_id — you need it for ALL API calls for this user
STEP 4: Make API calls
→ Headers: X-API-Key: <your_api_key>, X-User-ID: <user_id from step 3>
Sequence Diagram
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Your App │ │ app.ofself │ │ User │
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘
│ │ │
│ 1. Direct user to │ │
│ authorization URL │ │
│──────────────────────>│ │
│ │ 2. User logs in │
│ │<───────────────────────│
│ │ │
│ │ 3. Show app's │
│ │ requested permissions │
│ │───────────────────────>│
│ │ │
│ │ 4. User selects │
│ │ exposure profile │
│ │<───────────────────────│
│ │ │
│ │ 5. User approves │
│ │<───────────────────────│
│ │ │
│ 6. Redirect to your │ │
│ callback URL with │ │
│ code + client_id │ │
│ + user_id │ │
│<──────────────────────│ │
│ │ │
│ 7. Use API Key + │ │
│ X-User-ID to │ │
│ call APIs │ │
│──────────────────────>│ │
Step 1: Register Your App
Register your app via the Developer Dashboard (see Register Your App). You'll receive a client_id and an api_key. Include requested_permissions to declare what your app needs.
Step 2: Direct User to Authorize
Send the user to the OfSelf authorization page:
https://api.ofself.ai/api/v1/authorize?client_id=<your_client_id>&redirect_uri=<your_callback_url>
On this page, the user will:
- See your app's requested permissions
- Select an exposure profile that covers those permissions
- Approve the authorization
If the user's selected exposure profile doesn't cover all of your app's requested permissions, the Approve button is disabled. The user must select a different profile or customize permissions.
Step 3: Receive the Callback with User ID
After the user approves, OfSelf redirects to your redirect_uri with the following query parameters:
https://yourapp.com/callback?code=success&client_id=tp_abc123...&user_id=550e8400-e29b-41d4-a716-446655440000
| Parameter | Description |
|---|---|
code | Always success on approval |
client_id | Your app's client ID |
user_id | The UUID of the user who authorized your app |
You must persist the user_id from the callback. This is the only time you receive it, and you need it for every API call you make on behalf of this user.
Example: Handling the Callback
Python (Flask)
@app.route('/callback')
def ofself_callback():
code = request.args.get('code')
client_id = request.args.get('client_id')
user_id = request.args.get('user_id')
if code == 'success' and user_id:
# Store user_id in your database — you need it for all API calls
save_authorized_user(user_id)
return "Authorization successful!"
else:
return "Authorization failed", 400
JavaScript (Express)
app.get('/callback', (req, res) => {
const { code, client_id, user_id } = req.query;
if (code === 'success' && user_id) {
// Store user_id in your database — you need it for all API calls
saveAuthorizedUser(user_id);
res.send('Authorization successful!');
} else {
res.status(400).send('Authorization failed');
}
});
Step 4: Make API Calls
Once you have the user_id, use your API key and the user ID to make requests:
curl -X GET "https://api.ofself.ai/api/v1/nodes" \
-H "X-API-Key: ofs_tp_xxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" \
-H "X-User-ID: 550e8400-e29b-41d4-a716-446655440000"
Python SDK
from ofself import OfSelfClient
client = OfSelfClient(api_key="ofs_tp_xxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy")
# Access user's data (user_id from the authorization callback)
nodes = client.nodes.list(user_id="550e8400-e29b-41d4-a716-446655440000")
JavaScript SDK
import { OfSelfClient } from 'ofself-sdk';
const client = new OfSelfClient({
apiKey: 'ofs_tp_xxxxxxxxxxxx.yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
});
// Access user's data (userId from the authorization callback)
const nodes = await client.nodes.list({ userId: '550e8400-e29b-41d4-a716-446655440000' });
Complete End-to-End Example
Here's a full working example using Python (Flask):
import os
import requests
from flask import Flask, request, redirect
app = Flask(__name__)
API_KEY = os.environ["OFSELF_API_KEY"]
CLIENT_ID = os.environ["OFSELF_CLIENT_ID"]
REDIRECT_URI = "https://myapp.com/callback"
# Store authorized user IDs (use a database in production)
authorized_users = {}
# Step 2: Send user to authorize
@app.route('/connect-ofself')
def connect():
auth_url = f"https://api.ofself.ai/api/v1/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}"
return redirect(auth_url)
# Step 3: Handle the callback
@app.route('/callback')
def callback():
code = request.args.get('code')
user_id = request.args.get('user_id')
if code == 'success' and user_id:
# Store user_id — you need it for all future API calls
authorized_users[user_id] = True
return f"Connected! Your OfSelf user ID: {user_id}"
return "Authorization failed", 400
# Step 4: Make API calls using the stored user_id
@app.route('/my-nodes/<user_id>')
def get_nodes(user_id):
if user_id not in authorized_users:
return "User not authorized", 403
response = requests.get(
"https://api.ofself.ai/api/v1/nodes",
headers={
"X-API-Key": API_KEY,
"X-User-ID": user_id
}
)
return response.json()
Effective Permissions
At runtime, your app receives the intersection of:
- Your app's
requested_permissions(ceiling) - The user's exposure profile grants (what they chose to share)
Even if the user grants more than you requested, your app can only use what it declared.
Security Best Practices
- Never expose API keys client-side - Keep API keys server-side only
- Use HTTPS - All OfSelf endpoints require HTTPS
- Store user IDs securely - Treat authorized user IDs as sensitive data
- Validate callbacks - Check that the
client_idin the callback matches yours