# SerenAI - Full API Reference > Pay-per-query data marketplace for AI agents. Complete endpoint documentation. For a condensed overview, see [/llms.txt](/llms.txt). ## Base URL & Authentication ``` Base URL: https://api.serendb.com Authorization: Bearer seren_live_xxxxx ``` --- ## Agent Marketplace (Primary API) Query data publishers with pay-per-query pricing. This is the main API for AI agents. ### `POST /auth/agent` POST /auth/agent Register a new AI agent account. This endpoint allows AI agents to self-register and receive an API key immediately. Unlike the standard signup flow, agent registration: - Does NOT require email verification - Automatically creates a personal organization - Returns an API key named "agent" for immediate use **Important:** Save the `api_key` immediately - it is only shown once! **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ## Agent Wallet & Payments Manage prepaid balance and payment methods. ### `GET /wallet/balance` Get wallet balance (funded + promotional) **Response:** 200 --- ### `POST /wallet/bonus/payment-method` Claim payment method bonus (if not already claimed) **Response:** 200 --- ### `POST /wallet/bonus/signup` Claim signup bonus (if not already claimed) **Response:** 200 --- ### `POST /wallet/daily/claim` Claim daily free credits **Response:** 200 --- ### `GET /wallet/daily/eligibility` Check if user can claim daily credits **Response:** 200 --- ### `POST /wallet/deposit` Deposit funds via Stripe **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /wallet/deposit/crypto` Deposit configured asset via on-chain payment flow Allows agents to deposit the configured asset directly on-chain to their prepaid balance. Follows the 402 payment protocol: 1. First request (no payment header) returns 402 with payment requirements 2. Second request (with payment header) settles on-chain and credits balance **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /wallet/recover` POST /wallet/recover Recover an agent account using a recovery code. This endpoint allows agents who have lost their API key to recover their account using the recovery code they saved when setting up wallet recovery or on first deposit. **What this does:** - Verifies the recovery code - Revokes all existing API keys (for security) - Issues a new API key - Rotates the recovery code (old code is invalidated) **Important:** Save both the new API key AND the new recovery code - they're only shown once! **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /wallet/recovery` Set up account recovery (recovery code and/or email). - If you don't have a `recovery_code` yet, this endpoint generates one and returns it **once**. - If you already have a `recovery_code`, it will not be shown again. - You can optionally set/update a recovery `email` for human account recovery. Use the recovery code with `POST /wallet/recover` to rotate access after losing your API key. **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /wallet/referral` Get user's referral info and code **Response:** 200 --- ### `POST /wallet/referral/apply` Apply a referral code to the current user **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /wallet/transactions` Get transaction history for funded operations **Parameters:** - `limit` (integer): Maximum number of transactions to return (default 50, max 100) - `offset` (integer): Offset for pagination **Response:** 200 --- ## Agent Templates Discover and invoke pre-built agent templates. ### `GET /organizations/{organization_id}/templates/analytics/{publisher_id}` GET /organizations/{organization_id}/templates/analytics/{publisher_id} Get template analytics for a specific publisher **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Response:** 200 --- ### `GET /templates` GET /templates List available templates in the catalog **Parameters:** - `verified_only` (boolean): Filter to verified templates only - `language` (string): Filter by language (python, typescript, rust) - `min_price` (integer): Minimum price in atomic units - `max_price` (integer): Maximum price in atomic units - `search` (string): Search in name and description - `sort_by` (string): Sort order (popularity, price_asc, price_desc, newest, oldest) - `limit` (integer): Maximum number of templates to return (default: 50) - `offset` (integer): Offset for pagination (default: 0) **Response:** 200 --- ### `POST /templates/publish` POST /templates/publish Publish a new agent template **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /templates/{slug}` GET /templates/{slug} Get template details by slug **Parameters:** - `slug` (string *(required)*): Template slug **Response:** 200 --- ### `POST /templates/{slug}/invoke` POST /templates/{slug}/invoke Invoke an agent template. Supports two modes: - **Bearer auth present**: uses the authenticated user's SerenBucks balance. - **No bearer auth**: uses x402 (requires `X-AGENT-WALLET` + payment headers). **Parameters:** - `slug` (string *(required)*): Template slug **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ## Projects ### `GET /projects` List all projects for the authenticated user's organization **Parameters:** - `limit` (integer): Maximum number of items to return (default: 20, max: 100) - `offset` (integer): Number of items to skip (default: 0) - `show_service` (boolean): Show the organization service project (`seren-services`) in the results. **Response:** 200 --- ### `POST /projects` Create a new project **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /projects/{project_id}` Get a specific project by ID **Parameters:** - `project_id` (string *(required)*): Project ID **Response:** 200 --- ### `DELETE /projects/{project_id}` Delete a project **Parameters:** - `project_id` (string *(required)*): Project ID **Response:** 200 --- ### `PATCH /projects/{project_id}` Update a project **Parameters:** - `project_id` (string *(required)*): Project ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /projects/{project_id}/connection_uri` Retrieve a connection URI for the project control plane endpoint **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string): Branch ID to target (defaults to project's default branch) - `endpoint_id` (string): Endpoint ID to target (defaults to first endpoint in branch) - `database_name` (string): Database name override (currently ignored) - `role_name` (string): Role name override (currently ignored) - `pooled` (boolean): Return pooled connection (currently ignored) **Response:** 200 --- ### `GET /projects/{project_id}/size` Get project storage size **Parameters:** - `project_id` (string *(required)*): Project ID **Response:** 200 --- ## Databases ### `GET /databases` List all databases across all projects for the authenticated user Returns all databases the user has access to, with project and branch context included. This provides a single view of all databases without needing to query each project/branch separately. **Response:** 200 --- ### `GET /projects/{project_id}/branches/{branch_id}/databases` List all databases for a branch **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID **Response:** 200 --- ### `POST /projects/{project_id}/branches/{branch_id}/databases` Create a new database within a branch **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /projects/{project_id}/branches/{branch_id}/databases/{database_id}` Get a specific database by ID **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_id` (string *(required)*): Database ID **Response:** 200 --- ### `PUT /projects/{project_id}/branches/{branch_id}/databases/{database_id}` Update a database (currently only supports changing owner) **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_id` (string *(required)*): Database ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `DELETE /projects/{project_id}/branches/{branch_id}/databases/{database_id}` Delete a database **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_id` (string *(required)*): Database ID **Response:** 200 --- ### `GET /projects/{project_id}/branches/{branch_id}/databases/{database_name}` Get a specific database by name **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_name` (string *(required)*): Database name **Response:** 200 --- ### `DELETE /projects/{project_id}/branches/{branch_id}/databases/{database_name}` Delete a database by name **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_name` (string *(required)*): Database name **Response:** 200 --- ### `PATCH /projects/{project_id}/branches/{branch_id}/databases/{database_name}` Update a database by name (supports changing owner) **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `database_name` (string *(required)*): Database name **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /projects/{project_id}/databases` List all databases across all branches for a specific project Returns all databases in the project with branch context included. This provides a single view of all databases in a project without needing to query each branch separately. **Parameters:** - `project_id` (string *(required)*): Project ID **Response:** 200 --- ## Roles ### `GET /projects/{project_id}/branches/{branch_id}/roles` List all roles for a branch **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID **Response:** 200 --- ### `POST /projects/{project_id}/branches/{branch_id}/roles` Create a new role within a branch **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `DELETE /projects/{project_id}/branches/{branch_id}/roles/{role_id}` Delete a role **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_id` (string *(required)*): Role ID **Response:** 200 --- ### `POST /projects/{project_id}/branches/{branch_id}/roles/{role_id}/reset_password` Reset a role's password **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_id` (string *(required)*): Role ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /projects/{project_id}/branches/{branch_id}/roles/{role_name}` Get a role by name **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_name` (string *(required)*): Role name **Response:** 200 --- ### `DELETE /projects/{project_id}/branches/{branch_id}/roles/{role_name}` Delete a role by name **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_name` (string *(required)*): Role name **Response:** 200 --- ### `POST /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reset_password` Reset a role's password by name **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_name` (string *(required)*): Role name **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /projects/{project_id}/branches/{branch_id}/roles/{role_name}/reveal_password` Reveal password for a role by name (SerenDB-compatible endpoint) **Parameters:** - `project_id` (string *(required)*): Project ID - `branch_id` (string *(required)*): Branch ID - `role_name` (string *(required)*): Role name **Response:** 200 --- ## Agent Analytics ### `GET /organizations/{organization_id}/publishers/{publisher_id}/analytics/revenue` GET /organizations/:org_id/publishers/:publisher_id/analytics/revenue Get revenue metrics with period-over-period comparison. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID - `days` (integer): Number of days to analyze (default: 30) **Response:** 200 --- ### `GET /organizations/{organization_id}/publishers/{publisher_id}/analytics/revenue-by-day` GET /organizations/:org_id/publishers/:publisher_id/analytics/revenue-by-day Get daily revenue breakdown. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID - `days` (integer): Number of days to analyze (default: 30) **Response:** 200 --- ### `GET /organizations/{organization_id}/publishers/{publisher_id}/analytics/top-agents` GET /organizations/:org_id/publishers/:publisher_id/analytics/top-agents Get top agents by spending. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID - `limit` (integer): Number of agents to return (default: 10) **Response:** 200 --- ## Audit Logs ### `GET /organizations/{organization_id}/audit-logs` List audit logs for an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID - `actor_id` (string): Filter by actor ID - `action` (string): Filter by action (e.g., "project.create") - `resource_type` (string): Filter by resource type (e.g., "project", "branch") - `resource_id` (string): Filter by resource ID - `status` (string): Filter by status - `action_category` (string): Filter by action category - `start_date` (string): Filter by start date (ISO 8601) - `end_date` (string): Filter by end date (ISO 8601) - `limit` (integer): Maximum number of results (default 50, max 100) - `offset` (integer): Offset for pagination **Response:** 200 --- ### `GET /organizations/{organization_id}/audit-logs/{log_id}` Get a specific audit log entry **Parameters:** - `organization_id` (string *(required)*): Organization ID - `log_id` (string *(required)*): Audit log ID **Response:** 200 --- ## Auth ### `POST /auth/forgot-password` POST /auth/forgot-password Request a password reset email **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /auth/me` GET /auth/me Get current authenticated user information with default organization **Response:** 200 --- ### `POST /auth/resend-verification` POST /auth/resend-verification Resend email verification link **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /auth/reset-password` POST /auth/reset-password Reset password using a valid token **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /auth/verify-email` POST /auth/verify-email Verify email address using a token sent during signup On success, automatically logs the user in and returns tokens **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /organizations/default/api-keys` List API keys for the user's default organization **Response:** 200 --- ### `POST /organizations/default/api-keys` Create a new API key for the user's default organization This is a convenience endpoint that resolves "default" to the user's first organization, avoiding an extra round-trip to /auth/me. **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `DELETE /organizations/default/api-keys/{key_id}` Revoke an API key from the user's default organization **Parameters:** - `key_id` (string *(required)*): API key ID **Response:** 200 --- ### `GET /organizations/{organization_id}/api-keys` List API keys for a specific organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/api-keys` Create a new API key for a specific organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `DELETE /organizations/{organization_id}/api-keys/{key_id}` Revoke an organization API key **Parameters:** - `organization_id` (string *(required)*): Organization ID - `key_id` (string *(required)*): API key ID **Response:** 200 --- ## billing ### `GET /billing/health` GET /billing/health High-level billing and metering health summary for Seren Core **Response:** 200 --- ### `POST /billing/invoices/generate` POST /billing/invoices/generate Generate monthly invoices for all organizations **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /billing/invoices/{id}` GET /billing/invoices/:id Get invoice details with line items **Parameters:** - `id` (string *(required)*): Invoice ID **Response:** 200 --- ### `POST /billing/invoices/{id}/issue` POST /billing/invoices/:id/issue Issue a draft invoice **Parameters:** - `id` (string *(required)*): Invoice ID **Response:** 200 --- ### `GET /billing/usage/{organization_id}` GET /billing/usage/:organization_id Get usage summary for an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID - `start_date` (string): - `end_date` (string): **Response:** 200 --- ### `GET /organizations/{organization_id}/billing/endpoints/{endpoint_id}/events` GET /organizations/{organization_id}/billing/endpoints/{endpoint_id}/events Debug endpoint: show recent usage_events and compute_usage_events for an endpoint **Parameters:** - `organization_id` (string *(required)*): Organization ID - `endpoint_id` (string *(required)*): Endpoint ID **Response:** 200 --- ### `GET /organizations/{organization_id}/consumption` GET /organizations/{organization_id}/consumption Aggregated organization-level consumption over a billing window. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `start_date` (string): Optional ISO-8601 start date (YYYY-MM-DD), defaults to first day of current month. - `end_date` (string): Optional ISO-8601 end date (YYYY-MM-DD), defaults to today (UTC). **Response:** 200 --- ### `GET /projects/{project_id}/consumption` GET /projects/{project_id}/consumption Aggregated project-level consumption (compute, storage, PITR, network) over a billing window. **Parameters:** - `project_id` (string *(required)*): Project ID - `start_date` (string): Optional ISO-8601 start date (YYYY-MM-DD), defaults to first day of current month. - `end_date` (string): Optional ISO-8601 end date (YYYY-MM-DD), defaults to today (UTC). **Response:** 200 --- ## OAuth ### `GET /oauth/connections` List user's OAuth connections Returns all OAuth providers the user has connected to. **Response:** 200 --- ### `DELETE /oauth/connections/providers/{provider_id}` Revoke an OAuth connection by provider ID (supports org-scoped providers) **Parameters:** - `provider_id` (string *(required)*): OAuth provider UUID to disconnect **Response:** 200 --- ### `DELETE /oauth/connections/{provider}` Revoke an OAuth connection Disconnects the user's account from the OAuth provider and deletes stored tokens. **Parameters:** - `provider` (string *(required)*): OAuth provider slug to disconnect **Response:** 200 --- ### `GET /oauth/providers` List available OAuth providers Returns all active OAuth providers that users can connect to, including global providers and providers from organizations the user belongs to. **Response:** 200 --- ### `GET /oauth/providers/{provider_id}/authorize` Initiate OAuth authorization flow by provider ID (supports org-scoped providers) **Parameters:** - `provider_id` (string *(required)*): OAuth provider UUID - `redirect_uri` (string): Where to redirect after OAuth completes --- ### `GET /oauth/providers/{provider_id}/callback` Handle OAuth callback by provider ID (supports org-scoped providers) **Parameters:** - `provider_id` (string *(required)*): OAuth provider UUID - `code` (string *(required)*): Authorization code from provider - `state` (string *(required)*): State parameter for CSRF verification --- ### `GET /oauth/{provider}/authorize` Initiate OAuth authorization flow Redirects the user to the OAuth provider's consent screen. After authorization, the provider will redirect back to the callback URL. **Parameters:** - `provider` (string *(required)*): OAuth provider slug (e.g., 'neon') - `redirect_uri` (string): Where to redirect after OAuth completes --- ### `GET /oauth/{provider}/callback` Handle OAuth callback Called by the OAuth provider after the user authorizes. Exchanges the authorization code for tokens and stores them. **Parameters:** - `provider` (string *(required)*): OAuth provider slug - `code` (string *(required)*): Authorization code from provider - `state` (string *(required)*): State parameter for CSRF verification --- ## oauth-providers ### `GET /organizations/{organization_id}/oauth/providers` GET /organizations/{organization_id}/oauth/providers List all OAuth providers for an organization. **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/oauth/providers` POST /organizations/{organization_id}/oauth/providers Create a new OAuth provider for an organization. **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /organizations/{organization_id}/oauth/providers/{provider_id}` GET /organizations/{organization_id}/oauth/providers/{provider_id} Get a specific OAuth provider for an organization. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `provider_id` (string *(required)*): OAuth provider ID **Response:** 200 --- ### `DELETE /organizations/{organization_id}/oauth/providers/{provider_id}` DELETE /organizations/{organization_id}/oauth/providers/{provider_id} Delete an OAuth provider for an organization. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `provider_id` (string *(required)*): OAuth provider ID **Response:** 204 --- ### `PATCH /organizations/{organization_id}/oauth/providers/{provider_id}` PATCH /organizations/{organization_id}/oauth/providers/{provider_id} Update an OAuth provider for an organization. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `provider_id` (string *(required)*): OAuth provider ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ## Organizations ### `GET /organizations` GET /organizations List all organizations for the authenticated user **Response:** 200 --- ### `GET /organizations/{organization_id}/invites` GET /organizations/{organization_id}/invites List pending and historical organization invites. **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/invites` POST /organizations/{organization_id}/invites Create a new organization invite and send an email via the configured mailer. **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /organizations/{organization_id}/members` GET /organizations/{organization_id}/members List organization members with basic user details. **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `GET /organizations/{organization_id}/publishers` GET /organizations/:org_id/publishers List publishers owned by an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/publishers` POST /organizations/:org_id/publishers Create a new publisher **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /organizations/{organization_id}/publishers/{publisher_id}` GET /organizations/:org_id/publishers/:publisher_id Get publisher details **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Response:** 200 --- ### `PUT /organizations/{organization_id}/publishers/{publisher_id}` PUT /organizations/:org_id/publishers/:publisher_id Update a publisher **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `DELETE /organizations/{organization_id}/publishers/{publisher_id}` DELETE /organizations/:org_id/publishers/:publisher_id Soft delete a publisher **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Response:** 200 --- ### `GET /organizations/{organization_id}/publishers/{publisher_id}/earnings` GET /organizations/:org_id/publishers/:publisher_id/earnings List earnings for a publisher (per asset). **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Response:** 200 --- ### `POST /organizations/{organization_id}/publishers/{publisher_id}/logo` POST /organizations/{organization_id}/publishers/{publisher_id}/logo Upload a logo for a publisher **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /organizations/{organization_id}/publishers/{publisher_id}/payouts` GET /organizations/:org_id/publishers/:publisher_id/payouts List payout requests for a publisher. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID - `limit` (integer): Maximum number of results (default: 50) - `offset` (integer): Offset for pagination **Response:** 200 --- ### `POST /organizations/{organization_id}/publishers/{publisher_id}/payouts` POST /organizations/:org_id/publishers/:publisher_id/payouts Request a payout for a publisher's earnings. **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `PUT /organizations/{organization_id}/publishers/{publisher_id}/pricing` PUT /organizations/:org_id/publishers/:publisher_id/pricing Update publisher pricing config for a specific asset **Parameters:** - `organization_id` (string *(required)*): Organization ID - `publisher_id` (string *(required)*): Publisher ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ## payments ### `POST /billing/invoices/{id}/pay` POST /billing/invoices/:id/pay Create a payment intent for an invoice **Parameters:** - `id` (string *(required)*): Invoice ID **Response:** 200 --- ### `GET /billing/invoices/{id}/payments` GET /billing/invoices/:id/payments Get payment history for an invoice **Parameters:** - `id` (string *(required)*): Invoice ID **Response:** 200 --- ### `GET /billing/payment-methods` GET /billing/payment-methods List payment methods for the organization **Response:** 200 --- ### `POST /billing/payment-methods` POST /billing/payment-methods Add a payment method for the organization **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `DELETE /billing/payment-methods/{id}` DELETE /billing/payment-methods/{id} Remove a payment method from the organization **Parameters:** - `id` (string *(required)*): Payment method ID **Response:** 204 --- ### `GET /payments/supported` GET /payments/supported Returns supported x402 payment kinds for facilitator discovery. **Response:** 200 --- ## Plans ### `GET /organizations/{organization_id}/plan` GET /organizations/:org_id/plan Get the current plan for an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/plan` POST /organizations/:org_id/plan Upgrade or downgrade an organization's plan **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /organizations/{organization_id}/quota` GET /organizations/:org_id/quota Get current quota usage for an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `GET /plans` GET /plans List all available subscription plans **Response:** 200 --- ### `GET /plans/{plan_id}` GET /plans/:plan_id Get details of a specific plan **Parameters:** - `plan_id` (string *(required)*): Plan ID **Response:** 200 --- ## publisher-payments ### `POST /billing/publishers/{slug}/charges` POST /billing/publishers/{slug}/charges **Parameters:** - `slug` (string *(required)*): Publisher slug **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /billing/publishers/{slug}/charges/{charge_id}` GET /billing/publishers/{slug}/charges/{charge_id} **Parameters:** - `slug` (string *(required)*): Publisher slug - `charge_id` (string *(required)*): Charge ID **Response:** 200 --- ### `POST /billing/publishers/{slug}/charges/{charge_id}/refund` POST /billing/publishers/{slug}/charges/{charge_id}/refund **Parameters:** - `slug` (string *(required)*): Publisher slug - `charge_id` (string *(required)*): Charge ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /billing/publishers/{slug}/charges/{charge_id}/slash` POST /billing/publishers/{slug}/charges/{charge_id}/slash **Parameters:** - `slug` (string *(required)*): Publisher slug - `charge_id` (string *(required)*): Original charge ID **Request Body:** See OpenAPI spec for schema **Response:** 204 --- ### `POST /billing/publishers/{slug}/payouts` POST /billing/publishers/{slug}/payouts **Parameters:** - `slug` (string *(required)*): Publisher slug **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /billing/publishers/{slug}/payouts/{payout_id}` GET /billing/publishers/{slug}/payouts/{payout_id} **Parameters:** - `slug` (string *(required)*): Publisher slug - `payout_id` (string *(required)*): Payout ID **Response:** 200 --- ### `GET /wallet/lookup/{agent_wallet}` GET /wallet/lookup/{agent_wallet} Look up an agent's available balance (for publisher pre-checks) **Parameters:** - `agent_wallet` (string *(required)*): Agent wallet address **Response:** 200 --- ## publishers ### `GET /publishers` GET /publishers List publishers with full details and pricing (store view) **Parameters:** - `is_verified` (boolean): Filter by verification status - `category` (string): Filter by publisher category - `search` (string): Search by name or slug - `limit` (integer): Maximum number of results (default: 50, max: 100) - `offset` (integer): Offset for pagination **Response:** 200 --- ### `GET /publishers/suggest` GET /publishers/suggest Suggest publishers based on a task or query **Parameters:** - `query` (string *(required)*): The task or query to match against publisher capabilities. Examples: "scrape website", "AI research", "PDF extraction" - `type` (string): Type of suggestions: "publisher", "agent", or "both" (default: "both") Note: Agent suggestions are planned but not yet implemented. - `limit` (integer): Maximum number of results (default: 5, max: 20) **Response:** 200 --- ### `GET /publishers/{slug}` GET /publishers/{slug} Get publisher by slug (store view with full details) **Parameters:** - `slug` (string *(required)*): Publisher slug **Response:** 200 --- ### `POST /publishers/{slug}` Handle requests to the publisher root. For database publishers, this executes a query from the request body. For API publishers, this proxies to the root endpoint. For MCP publishers, this returns an error (use specific tool/resource endpoints). **Parameters:** - `slug` (string *(required)*): Publisher slug identifier **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `POST /publishers/{slug}/estimate` Estimate query cost without payment **Parameters:** - `slug` (string *(required)*): Publisher slug **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /publishers/{slug}/logo` GET /publishers/{slug}/logo Fetch publisher logo (inline data or redirect to URL) Accepts either publisher slug or UUID for backwards compatibility **Parameters:** - `slug` (string *(required)*): Publisher slug or UUID **Response:** 200 --- ### `GET /publishers/{slug}/{path}` **Parameters:** - `slug` (string *(required)*): Publisher slug identifier - `path` (string *(required)*): Path to proxy to the publisher **Response:** 200 --- ### `POST /publishers/{slug}/{path}` **Parameters:** - `slug` (string *(required)*): Publisher slug identifier - `path` (string *(required)*): Path to proxy to the publisher **Response:** 200 --- ## RBAC ### `PUT /organizations/{organization_id}/members/{member_id}/role` Assign a role to an organization member **Parameters:** - `organization_id` (string *(required)*): Organization ID - `member_id` (string *(required)*): Member user ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /organizations/{organization_id}/permissions/check/{permission}` Check if the current user has a specific permission **Parameters:** - `organization_id` (string *(required)*): Organization ID - `permission` (string *(required)*): Permission name to check **Response:** 200 --- ### `GET /organizations/{organization_id}/permissions/mine` Get current user's permissions in an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `GET /organizations/{organization_id}/roles` List roles for an organization (includes built-in roles) **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/roles` Create a custom role **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /organizations/{organization_id}/roles/{role_id}` Get a specific role **Parameters:** - `organization_id` (string *(required)*): Organization ID - `role_id` (string *(required)*): Role ID **Response:** 200 --- ### `DELETE /organizations/{organization_id}/roles/{role_id}` Delete a custom role **Parameters:** - `organization_id` (string *(required)*): Organization ID - `role_id` (string *(required)*): Role ID **Response:** 204 --- ### `PATCH /organizations/{organization_id}/roles/{role_id}` Update a custom role **Parameters:** - `organization_id` (string *(required)*): Organization ID - `role_id` (string *(required)*): Role ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /permissions` List all permissions **Response:** 200 --- ## Sessions ### `GET /sessions` List all active sessions for the current user **Response:** 200 --- ### `POST /sessions/revoke-all` Revoke all sessions (logout everywhere) **Response:** 200 --- ### `DELETE /sessions/{session_id}` Revoke a specific session **Parameters:** - `session_id` (string *(required)*): Session ID to revoke **Response:** 200 --- ### `POST /sessions/{session_id}/revoke-others` Revoke all sessions except a specified one **Parameters:** - `session_id` (string *(required)*): Session ID to keep (current session) **Response:** 200 --- ## webhooks ### `POST /webhooks/stripe` POST /webhooks/stripe Handle Stripe webhook events **Response:** 200 --- ## Webhooks ### `GET /organizations/{organization_id}/webhooks` List webhooks for an organization **Parameters:** - `organization_id` (string *(required)*): Organization ID **Response:** 200 --- ### `POST /organizations/{organization_id}/webhooks` Create a webhook **Parameters:** - `organization_id` (string *(required)*): Organization ID **Request Body:** See OpenAPI spec for schema **Response:** 201 --- ### `GET /organizations/{organization_id}/webhooks/{webhook_id}` Get a specific webhook **Parameters:** - `organization_id` (string *(required)*): Organization ID - `webhook_id` (string *(required)*): Webhook ID **Response:** 200 --- ### `DELETE /organizations/{organization_id}/webhooks/{webhook_id}` Delete a webhook **Parameters:** - `organization_id` (string *(required)*): Organization ID - `webhook_id` (string *(required)*): Webhook ID **Response:** 204 --- ### `PATCH /organizations/{organization_id}/webhooks/{webhook_id}` Update a webhook **Parameters:** - `organization_id` (string *(required)*): Organization ID - `webhook_id` (string *(required)*): Webhook ID **Request Body:** See OpenAPI spec for schema **Response:** 200 --- ### `GET /organizations/{organization_id}/webhooks/{webhook_id}/deliveries` List recent deliveries for a webhook **Parameters:** - `organization_id` (string *(required)*): Organization ID - `webhook_id` (string *(required)*): Webhook ID **Response:** 200 --- ### `POST /organizations/{organization_id}/webhooks/{webhook_id}/rotate-secret` Regenerate webhook secret **Parameters:** - `organization_id` (string *(required)*): Organization ID - `webhook_id` (string *(required)*): Webhook ID **Response:** 200 --- ### `GET /webhooks/event-types` List available event types **Response:** 200 --- ## Branch Protection (Infrastructure) - `GET /projects/{project_id}/branch-protection` - List branch protection rules for a project - `GET /projects/{project_id}/branches/{branch_id}/protection` - Get branch protection rule for a specific branch - `POST /projects/{project_id}/branches/{branch_id}/protection` - Create branch protection rule - `DELETE /projects/{project_id}/branches/{branch_id}/protection` - Delete branch protection rule - `PATCH /projects/{project_id}/branches/{branch_id}/protection` - Update branch protection rule --- ## Branches (Infrastructure) - `GET /projects/{project_id}/branches` - List all branches for a project - `POST /projects/{project_id}/branches` - Create a new branch for a project - `GET /projects/{project_id}/branches/count` - Get branch count for a project - `GET /projects/{project_id}/branches/{branch_id}` - Get a specific branch by ID - `DELETE /projects/{project_id}/branches/{branch_id}` - Delete a branch - `PATCH /projects/{project_id}/branches/{branch_id}` - Rename a branch - `PATCH /projects/{project_id}/branches/{branch_id}/archived` - Set branch archived status - `GET /projects/{project_id}/branches/{branch_id}/connection-string` - Get connection string for a branch - `GET /projects/{project_id}/branches/{branch_id}/details` - Get detailed branch information including LSN and disk usage - `PATCH /projects/{project_id}/branches/{branch_id}/expiration` - Set branch expiration - `GET /projects/{project_id}/branches/{branch_id}/lsn_by_timestamp` - Get LSN for a specific timestamp on a branch - `POST /projects/{project_id}/branches/{branch_id}/reset` - Reset a branch to its parent's latest state - `POST /projects/{project_id}/branches/{branch_id}/restore` - Restore a branch to a point in time - `POST /projects/{project_id}/branches/{branch_id}/set-default` - Set a branch as the default branch for its project - `POST /projects/{project_id}/branches/{branch_id}/set_as_default` - Alias endpoint for setting branch as default using snake_case path - `GET /projects/{project_id}/branches/{branch_id}/timestamp_by_lsn` - Get timestamp for a specific LSN on a branch --- ## Endpoints (Infrastructure) - `GET /projects/{project_id}/branches/{branch_id}/endpoints` - List all endpoints for a branch - `POST /projects/{project_id}/branches/{branch_id}/endpoints` - Create a new endpoint (compute instance) for a branch - `DELETE /projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}` - Delete an endpoint - `PATCH /projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}` - Update an endpoint - `POST /projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}/start` - - `GET /projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}/status` - - `POST /projects/{project_id}/branches/{branch_id}/endpoints/{endpoint_id}/stop` - - `GET /projects/{project_id}/endpoints` - List all endpoints for a project (across branches) - `DELETE /projects/{project_id}/endpoints/{endpoint_id}` - Delete an endpoint by endpoint id within a project - `PATCH /projects/{project_id}/endpoints/{endpoint_id}` - Update an endpoint by endpoint id within a project - `POST /projects/{project_id}/endpoints/{endpoint_id}/restart` - Restart an endpoint by endpoint id within a project - `POST /projects/{project_id}/endpoints/{endpoint_id}/start` - Start an endpoint by endpoint id within a project - `POST /projects/{project_id}/endpoints/{endpoint_id}/suspend` - Suspend an endpoint by endpoint id within a project --- ## IP Allow Lists (Infrastructure) - `GET /projects/{project_id}/ip-allow` - List all IP allow list entries for a project - `POST /projects/{project_id}/ip-allow` - Add an IP address to the allow list - `PUT /projects/{project_id}/ip-allow/reset` - Replace the entire IP allow list with new entries - `DELETE /projects/{project_id}/ip-allow/{ip_id}` - Remove an IP address from the allow list --- ## Logical Replication (Infrastructure) - `GET /projects/{project_id}/branches/{branch_id}/publications` - List publications for a branch - `POST /projects/{project_id}/branches/{branch_id}/publications` - Create a publication - `DELETE /projects/{project_id}/branches/{branch_id}/publications/{publication_id}` - Delete a publication - `PATCH /projects/{project_id}/branches/{branch_id}/publications/{publication_id}` - Update a publication - `GET /projects/{project_id}/branches/{branch_id}/replication-slots` - List replication slots for a branch - `POST /projects/{project_id}/branches/{branch_id}/replication-slots` - Create a replication slot - `DELETE /projects/{project_id}/branches/{branch_id}/replication-slots/{slot_id}` - Delete a replication slot - `GET /projects/{project_id}/replication` - Get logical replication settings for a project - `PATCH /projects/{project_id}/replication` - Update logical replication settings for a project --- ## Operations (Infrastructure) - `GET /projects/{project_id}/operations` - List all operations for a project - `GET /projects/{project_id}/operations/{operation_id}` - Get a specific operation by ID --- ## VPC (Infrastructure) - `GET /organizations/{organization_id}/vpc-endpoints` - - `POST /organizations/{organization_id}/vpc-endpoints` - - `GET /organizations/{organization_id}/vpc-endpoints/{endpoint_id}` - - `DELETE /organizations/{organization_id}/vpc-endpoints/{endpoint_id}` - - `GET /organizations/{organization_id}/vpc/region/{region_id}/vpc_endpoints` - List VPC endpoints for an organization filtered by region (alias path) - `GET /organizations/{organization_id}/vpc/region/{region_id}/vpc_endpoints/{endpoint_id}` - Get VPC endpoint details with region in path (alias) - `DELETE /organizations/{organization_id}/vpc/region/{region_id}/vpc_endpoints/{endpoint_id}` - Delete VPC endpoint with region in path (alias) - `GET /organizations/{organization_id}/vpc/vpc_endpoints` - List VPC endpoints for an organization (alias path with underscores) - `GET /projects/{project_id}/vpc-endpoints` - - `POST /projects/{project_id}/vpc-endpoints` - - `DELETE /projects/{project_id}/vpc-endpoints/{assignment_id}` - - `GET /projects/{project_id}/vpc_endpoints` - List project VPC endpoint assignments (alias path with underscores) - `POST /projects/{project_id}/vpc_endpoints/{vpc_endpoint_id}` - Assign a VPC endpoint to a project by endpoint id in path (alias) - `DELETE /projects/{project_id}/vpc_endpoints/{vpc_endpoint_id}` - Remove a VPC endpoint assignment by VPC endpoint id (alias) --- ## Key Schemas ### CreatePublisherRequest Complete schema for creating a publisher. All fields except required ones are optional. **Required fields:** `name`, `slug`, `wallet_address`, `wallet_network_id` ```json { "name": "string (required) - Display name", "slug": "string (required) - URL-friendly unique identifier", "wallet_address": "string (required) - 0x... Ethereum address for payments", "wallet_network_id": "string (required) - CAIP-2 format, e.g., 'eip155:8453' for Base", "description": "string - Publisher description", "logo_url": "string - URL to publisher logo", "categories": ["string"] - e.g., ["blockchain", "finance"], "capabilities": ["string"] - e.g., ["sql_query", "web_scraping"], "use_cases": ["string"] - Human-readable use case descriptions, "source_type": "string - 'serendb' | 'neon' | 'supabase' | 'api'", "billing_model": "string - 'x402_per_request' | 'prepaid_credits' | 'x402_passthrough'", "api_url": "string - External API URL (required for api source_type)", "api_key_header": "string - Header name for API key injection (e.g., 'Authorization')", "api_key_query_param": "string - Query param for API key injection", "upstream_api_key": "string - API key for upstream service (encrypted)", "project_id": "uuid - SerenDB project ID (for serendb source_type)", "branch_id": "uuid - SerenDB branch ID (for serendb source_type)", "database_name": "string - Database name (default: 'serendb')", "base_price_per_1000_rows": "decimal string - e.g., '0.001'", "price_per_call": "decimal string - e.g., '0.01'", "price_per_get": "decimal string", "price_per_post": "decimal string", "price_per_put": "decimal string", "price_per_patch": "decimal string", "price_per_delete": "decimal string", "resource_name": "string - Display name for the resource", "resource_description": "string - Description of what the resource provides" } ``` **Example - Create an API publisher:** ```bash curl -X POST "https://api.serendb.com/agent/publishers" \ -H "Authorization: Bearer $SEREN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "My Weather API", "slug": "my-weather-api", "description": "Real-time weather data", "wallet_address": "0x83334ef0C6f6396413C508A7762741e9FD8B20E9", "wallet_network_id": "eip155:8453", "source_type": "api", "api_url": "https://api.weather-service.com", "api_key_header": "X-API-Key", "upstream_api_key": "your-api-key", "billing_model": "x402_per_request", "price_per_call": "0.001" }' ``` ### Publisher A data publisher in the agent marketplace. ```json { "id": "uuid", "slug": "string (unique identifier for API calls)", "name": "string", "description": "string", "is_verified": "boolean", "pricing": { "asset": "USDC", "price_per_query": "decimal" }, "categories": ["string"], "capabilities": ["database", "api", "streaming"] } ``` ### Query Response Response from `/agent/database` or `/agent/api`. ```json { "data": { "rows": [...], "columns": [...] }, "cost": { "amount": "0.01", "asset": "USDC" }, "publisher": { "slug": "publisher-slug", "name": "Publisher Name" } } ``` ### Wallet Balance Response from `/agent/wallet/balance`. ```json { "funded_balance": "10.50", "promotional_balance": "5.00", "total_balance": "15.50", "asset": "USDC" } ``` ### UpdatePublisherPricingRequest Configure pricing for a publisher. ```json { "price_per_call": "decimal string - Default price per API call", "price_per_get": "decimal string - Price for GET requests", "price_per_post": "decimal string - Price for POST requests", "price_per_put": "decimal string - Price for PUT requests", "price_per_patch": "decimal string - Price for PATCH requests", "price_per_delete": "decimal string - Price for DELETE requests", "base_price_per_1000_rows": "decimal string - Price per 1000 rows (database)", "min_charge": "decimal string - Minimum charge per request", "max_charge": "decimal string - Maximum charge per request", "prepaid_enabled": "boolean - Accept SerenBucks payments", "onchain_enabled": "boolean - Accept on-chain x402 payments" } ``` **Example - Configure pricing:** ```bash curl -X PUT "https://api.serendb.com/agent/publishers/my-api/pricing" \ -H "Authorization: Bearer $SEREN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price_per_call": "0.01", "min_charge": "0.001", "prepaid_enabled": true, "onchain_enabled": true }' ``` ### Project A database project for self-hosted data. ```json { "id": "uuid", "name": "string", "region": "us-east-1 | eu-west-1 | ...", "created_at": "timestamp", "default_branch_id": "uuid" } ``` --- For the complete OpenAPI specification: https://api.serendb.com/openapi.json