API Reference
REST API for managing Hydra workflows and deployments.
Base URL
The API base URL depends on your environment:
| Environment | Base URL |
|---|---|
| Dev | https://zl5lywlc5d.execute-api.us-west-2.amazonaws.com/v1 |
| Beta | https://u3srgjr1uf.execute-api.us-west-2.amazonaws.com/v1 |
| Production | https://1k2cc1sqa7.execute-api.us-west-2.amazonaws.com/v1 |
The web dashboard automatically uses the correct API URL based on the domain you're accessing.
Authentication
All API requests require a Bearer token (Cognito ID token):
curl -H "Authorization: Bearer YOUR_ID_TOKEN" \
https://API_BASE_URL/workflowsTokens are obtained through Cognito authentication. The web dashboard handles this automatically.
Workflows
List Workflows
GET /workflowsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | number | Max results (default: 20) |
cursor | string | Pagination cursor |
visibility | string | Filter: "public" or "private" |
Response:
{
"success": true,
"data": [
{
"workflowId": "wf_abc123",
"name": "Bug Fix Workflow",
"description": "Find and fix bugs",
"visibility": "public",
"category": "development",
"tags": ["bug-fix", "testing"],
"currentVersion": "1.2.0",
"stats": {
"forks": 15,
"subscribers": 42,
"rating": 4.5,
"ratingCount": 12
},
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-20T14:30:00Z"
}
],
"pagination": {
"nextCursor": "eyJsYXN0...",
"hasMore": true,
"count": 20
}
}Get Workflow
GET /workflows/{workflowId}Response:
{
"success": true,
"data": {
"workflowId": "wf_abc123",
"name": "Bug Fix Workflow",
"manifest": {
"$schema": "https://hydra.opiusai.com/schemas/workflow/v1.0.json",
"manifest_version": "1.0",
"name": "Bug Fix Workflow",
"steps": [...]
},
...
}
}Create Workflow
POST /workflowsRequest Body:
{
"name": "My Workflow",
"description": "Description of the workflow",
"manifest": {
"$schema": "https://hydra.opiusai.com/schemas/workflow/v1.0.json",
"manifest_version": "1.0",
"name": "My Workflow",
"steps": [...]
},
"visibility": "private",
"category": "development",
"tags": ["custom", "automation"]
}Response: 201 Created
{
"success": true,
"data": {
"workflowId": "wf_xyz789",
...
}
}Update Workflow
PUT /workflows/{workflowId}Request Body: Same as Create
Response: 200 OK
Delete Workflow
DELETE /workflows/{workflowId}Response: 200 OK
{
"success": true,
"data": {
"workflowId": "wf_abc123",
"deleted": true
}
}Deployments
MCP Deployments bundle your workflows into a single endpoint that your IDE can connect to.
List Deployments
GET /deploymentsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: "active" or "inactive" |
limit | number | Max results (default: 20, max: 100) |
cursor | string | Pagination cursor |
Response:
{
"success": true,
"data": [
{
"deploymentId": "dep_abc123",
"name": "Production Deploy",
"description": "Main production workflows",
"workflows": [
{ "workflowId": "wf_xyz789", "name": "Bug Fix", "version": "1.0.0", "isOwned": true }
],
"enabledAdapters": ["claude", "cursor", "codex"],
"status": "active",
"allowAnonymous": false,
"mcpEndpoint": "https://API_BASE_URL/mcp/dep_abc123",
"usage": {
"connectionsThisMonth": 145,
"lastConnectedAt": "2024-01-20T14:30:00Z"
},
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-20T14:30:00Z"
}
],
"pagination": {
"nextCursor": "eyJsYXN0...",
"hasMore": true,
"count": 20
}
}Get Deployment
GET /deployments/{deploymentId}Response:
{
"success": true,
"data": {
"deploymentId": "dep_abc123",
"name": "Production Deploy",
"description": "Main production workflows",
"workflows": [
{
"workflowId": "wf_xyz789",
"name": "Bug Fix Workflow",
"version": "1.2.0",
"isOwned": true
}
],
"enabledAdapters": ["claude", "cursor"],
"status": "active",
"allowAnonymous": false,
"mcpEndpoint": "https://API_BASE_URL/mcp/dep_abc123",
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-20T14:30:00Z"
}
}Create Deployment
POST /deploymentsRequest Body:
{
"name": "My Deployment",
"description": "Optional description",
"workflowIds": ["wf_abc123", "wf_xyz789"],
"enabledAdapters": ["claude", "cursor", "codex"],
"allowAnonymous": false
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Deployment name (max 100 chars) |
description | string | No | Optional description |
workflowIds | string[] | Yes | Array of workflow IDs to include (owned or subscribed) |
enabledAdapters | string[] | No | Adapters to enable: "claude", "cursor", "codex" (default: all) |
allowAnonymous | boolean | No | Allow unauthenticated MCP access (default: false) |
Response: 201 Created
{
"success": true,
"data": {
"deploymentId": "dep_xyz789",
"name": "My Deployment",
"mcpEndpoint": "https://API_BASE_URL/mcp/dep_xyz789",
"status": "active",
"enabledAdapters": ["claude", "cursor", "codex"],
"allowAnonymous": false,
"workflows": [
{ "workflowId": "wf_abc123", "name": "Workflow A", "version": "1.0.0", "isOwned": true }
],
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:00:00Z"
}
}Update Deployment
PUT /deployments/{deploymentId}Request Body:
{
"name": "Updated Name",
"description": "Updated description",
"workflowIds": ["wf_abc123", "wf_new456"],
"enabledAdapters": ["claude"],
"allowAnonymous": true
}| Field | Type | Description |
|---|---|---|
name | string | New deployment name |
description | string | New description (null to remove) |
workflowIds | string[] | Update included workflows (must own or be subscribed) |
enabledAdapters | string[] | Update enabled adapters |
allowAnonymous | boolean | Toggle anonymous MCP access |
Response: 200 OK
Enable/Disable Adapter
POST /deployments/{deploymentId}/adaptersRequest Body:
{
"adapter": "cursor",
"enabled": true
}| Field | Type | Description |
|---|---|---|
adapter | string | Adapter name: "claude", "cursor", or "codex" |
enabled | boolean | true to enable, false to disable |
Response: 200 OK
{
"success": true,
"data": {
"deploymentId": "dep_abc123",
"enabledAdapters": ["claude", "cursor"]
}
}Deactivate Deployment
Temporarily disable a deployment without deleting it:
POST /deployments/{deploymentId}/deactivateResponse: 200 OK
Activate Deployment
Re-enable a deactivated deployment:
POST /deployments/{deploymentId}/activateResponse: 200 OK
Delete Deployment
Permanently delete a deployment. This immediately disconnects all IDEs using the endpoint.
DELETE /deployments/{deploymentId}Response: 200 OK
{
"success": true,
"data": {
"deploymentId": "dep_abc123",
"deleted": true
}
}This action cannot be undone. All connected IDEs will immediately lose access.
Get Deployment Usage
Get detailed usage statistics for a deployment:
GET /deployments/{deploymentId}/usageQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
period | string | "day", "week", "month" (default: "month") |
Response:
{
"success": true,
"data": {
"deploymentId": "dep_abc123",
"period": "month",
"connections": {
"total": 145,
"limit": 500,
"remaining": 355
},
"byAdapter": {
"claude": 89,
"cursor": 45,
"codex": 11
},
"byDay": [
{ "date": "2024-01-15", "count": 12 },
{ "date": "2024-01-16", "count": 18 }
]
}
}Marketplace
Browse Marketplace
GET /marketplaceQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
category | string | Filter by category |
sort | string | "popular", "recent", "rating" |
limit | number | Max results |
cursor | string | Pagination cursor |
Search Marketplace
GET /marketplace/search?q={query}Get Featured Workflows
GET /marketplace/featuredLibrary
The Library is where users manage workflows they want to use. It includes both owned workflows and workflows added from the marketplace.
List Library Entries
GET /libraryQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | number | Max results (default: 20) |
cursor | string | Pagination cursor |
activeOnly | boolean | Only return active entries (default: false) |
Response:
{
"success": true,
"data": [
{
"libraryId": "lib_abc123",
"workflowId": "wf_xyz789",
"userId": "user-id",
"sourceType": "subscribed",
"sourceUserId": "owner-id",
"isActive": true,
"enabledAdapters": ["claude", "cursor"],
"workflowName": "Code Review Assistant",
"workflowVersion": "1.2.0",
"autoUpdate": true,
"addedAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-20T14:30:00Z"
}
],
"pagination": {
"nextCursor": "eyJsYXN0...",
"hasMore": true,
"count": 20
}
}Add to Library
POST /library/{workflowId}Request Body:
{
"enabledAdapters": ["claude", "cursor"],
"autoUpdate": true
}| Field | Type | Required | Description |
|---|---|---|---|
enabledAdapters | string[] | No | Adapters to enable: "claude", "cursor", "codex" (default: all) |
autoUpdate | boolean | No | Auto-update when source workflow is updated (default: true) |
Response: 201 Created
Update Library Entry
PATCH /library/{workflowId}Request Body:
{
"isActive": false,
"enabledAdapters": ["claude"]
}Response: 200 OK
Remove from Library
DELETE /library/{workflowId}Response: 200 OK
Copy (Fork)
Copy creates a new workflow owned by you based on an existing public workflow. The copy is fully independent and can be modified.
Copy Workflow
POST /workflows/{workflowId}/forkRequest Body:
{
"name": "My Custom Workflow"
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Name for the copy (default: "Original Name (copy)") |
Response: 201 Created
{
"success": true,
"data": {
"workflowId": "wf_copy123",
"name": "My Custom Workflow",
"forkedFrom": {
"workflowId": "wf_abc123",
"userId": "owner-id",
"version": "1.2.0"
},
"createdAt": "2024-01-15T10:00:00Z"
}
}The copied workflow is automatically added to your Library.
Users
Get Current User
GET /users/meResponse:
{
"success": true,
"data": {
"userId": "abc123-def456-...",
"email": "user@example.com",
"workflowCount": 12,
"deploymentCount": 3,
"subscriptionCount": 5,
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-20T14:30:00Z"
}
}Delete User Account
Permanently delete your account and all associated data. This performs a cascade deletion of:
- All workflows (and their versions)
- All deployments (and their prompts)
- All subscriptions
- Billing records
- User profile
DELETE /users/meResponse: 200 OK
{
"success": true,
"data": {
"userId": "abc123-def456-...",
"deleted": true,
"deletedAt": "2024-01-20T14:30:00Z",
"stats": {
"workflows": 5,
"workflowVersions": 12,
"deployments": 2,
"deploymentPrompts": 6,
"deploymentLookups": 2,
"subscriptions": 3,
"subscriberEntries": 3,
"billingRecords": 1
}
}
}This action cannot be undone. All your data will be permanently deleted.
Billing
Get Subscription
Get current user's billing subscription status.
GET /billing/subscriptionResponse:
{
"success": true,
"data": {
"plan": "pro",
"status": "active",
"customerId": "cus_xxx",
"subscriptionId": "sub_xxx",
"currentPeriodStart": "2024-01-01T00:00:00Z",
"currentPeriodEnd": "2024-02-01T00:00:00Z",
"cancelAtPeriodEnd": false
}
}Create Checkout Session
Create a Stripe checkout session to upgrade your plan.
POST /billing/checkoutRequest Body:
{
"priceId": "pro_monthly",
"successUrl": "https://hydra.opiusai.com/dashboard?upgraded=true",
"cancelUrl": "https://hydra.opiusai.com/pricing"
}| Field | Type | Required | Description |
|---|---|---|---|
priceId | string | Yes | Plan ID: "pro_monthly", "pro_annual", "team_monthly", "team_annual" |
successUrl | string | Yes | Redirect URL after successful payment |
cancelUrl | string | Yes | Redirect URL if user cancels |
Response: 200 OK
{
"success": true,
"data": {
"checkoutUrl": "https://checkout.stripe.com/..."
}
}Create Portal Session
Create a Stripe billing portal session to manage your subscription.
POST /billing/portalRequest Body:
{
"returnUrl": "https://hydra.opiusai.com/dashboard"
}Response: 200 OK
{
"success": true,
"data": {
"portalUrl": "https://billing.stripe.com/..."
}
}Error Responses
All errors follow this format:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable message",
"details": {}
}
}Error Codes
| Code | HTTP Status | Description |
|---|---|---|
VALIDATION_ERROR | 400 | Invalid request body |
UNAUTHORIZED | 401 | Missing or invalid token |
FORBIDDEN | 403 | Insufficient permissions |
NOT_FOUND | 404 | Resource not found |
CONFLICT | 409 | Resource conflict |
PLAN_LIMIT_EXCEEDED | 402 | Plan limit reached |
RATE_LIMITED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error |
Rate Limits
| Plan | Requests/Minute | Requests/Hour |
|---|---|---|
| Free | 30 | 500 |
| Pro | 100 | 5,000 |
| Team | 300 | 20,000 |
| Enterprise | 1,000 | 100,000 |
Rate limit headers are included in all responses:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1706097600SDKs
Official SDKs coming soon:
- JavaScript/TypeScript
- Python
- Go