rendry-io Accounts API

The Accounts API from rendry-io — 3 operation(s) for accounts.

Operations 5

GET /accounts List current browser memberships #
POST /accounts Create a team account #
GET /accounts/{account}/members List team members #
PUT /accounts/{account}/members/{actor} Add or change a registered member role #
DELETE /accounts/{account}/members/{actor} Remove a member without deleting account resources #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/rendry-io:rendry-io-accounts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

rendry-io-accounts-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Rendry Accounts API
  version: 1.6.0
  description: 'Template-based image generation API. Design a template in the visual editor (or via POST /presets), then render on-brand images with one call. Every capability the MCP server exposes as a tool is reachable over REST as well — same implementation behind both, so the two never drift. For AI agents a remote MCP endpoint is available at /mcp (streamable HTTP) — see https://rendry.io/llms-full.txt. Every refusal, on every door, is one JSON object {error: machine code, message: sentence, …fields} with the HTTP status of its class — see the Refusal schema; an MCP tool error carries the same object as its text.


    Authentication: four bearer credentials open the render and template doors — a persisted live or test API key (sk_live_… / sk_test_…), the browser session of the signed-in owner (the JWT POST /auth/login returns) a connector token (the JWT the OAuth flow issues to an MCP client), and an ephemeral editor session (em_…). Browser/OAuth credentials may select a current team membership with X-Rendry-Account; API keys and embed sessions are bound to their persisted account and cannot switch accounts. GET /principal returns the resolved authority. Roles and scopes intersect; a removed member immediately loses access. Test mode is persisted on the credential: renders retain all admission limits, cost zero credits and carry a RENDRY TEST watermark; test credentials cannot publish public links. Operations that list the `session` scheme alone are the account cabinet: an API key is refused there with 401, a connector token with 403 `browser_session_required` (account deletion: `account_deletion_needs_session`). Operations with an empty `security` are public.


    Also served, not described operation by operation: GET /templates/{id}/preview.png and GET /template-assets/{name} (public; the gallery''s pictures), GET /assets/library (public; the built-in image stock), GET /plans, GET /billing/config and GET /version (public; prices and the running build), GET /openapi.json (public; this document), POST /feedback (public, rate-limited by IP) and POST /feedback/agent (render credentials), the OAuth 2.1 doors under /oauth (the three /.well-known discovery documents, /register, /authorize, /client-info, /token — public; POST /oauth/decision takes the owner''s session), the guest batch under /batch-tasks/guest (public, rate-limited by IP: POST /preview, POST, GET /{token}, GET /{token}/archive), the sign-in, sign-up, e-mail verification and password doors under /auth (public; POST /auth/verify/resend takes the owner''s session), the cabinet''s POST /user/password, POST /checkout, GET /billing/history, GET /billing/subscription, GET /photos/search and POST /photos/used (owner''s session only), the payment webhooks POST /billing/webhook and POST /billing/webhook/{provider} (signed by the provider), the /internal/* doors of the render nodes (internal token) and the /admin group (administrators, session only).'
  contact:
    url: https://rendry.io
servers:
- url: https://rendry.io/api/v1
  description: Production
security:
- apiKey: []
- session: []
- connector: []
- embed: []
tags:
- name: Accounts
paths:
  /accounts:
    get:
      operationId: listAccounts
      summary: List current browser memberships
      description: ''
      responses:
        '200':
          description: List current browser memberships
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Account'
        '400':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '401':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '403':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '404':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '409':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '429':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
      security:
      - session: []
      parameters:
      - $ref: '#/components/parameters/AccountSelector'
      tags:
      - Accounts
    post:
      operationId: createAccount
      summary: Create a team account
      description: ''
      responses:
        '201':
          description: Create a team account
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Account'
        '400':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '401':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '403':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '404':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '409':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '429':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 255
              required:
              - name
      security:
      - session: []
      parameters:
      - $ref: '#/components/parameters/AccountSelector'
      tags:
      - Accounts
  /accounts/{account}/members:
    get:
      operationId: listAccountMembers
      summary: List team members
      description: Owner or admin browser authority for this account; member identifiers are an existing actor UUID or a registered email address.
      responses:
        '200':
          description: List team members
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AccountMember'
        '400':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '401':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '403':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '404':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '409':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '429':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
      security:
      - session: []
      parameters:
      - name: account
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/AccountSelector'
      tags:
      - Accounts
  /accounts/{account}/members/{actor}:
    put:
      operationId: setAccountMember
      summary: Add or change a registered member role
      description: Owner or admin required. The last owner cannot be removed or demoted. The actor path accepts an existing actor UUID or registered email address. This endpoint does not send an invitation.
      responses:
        '204':
          description: Add or change a registered member role
        '400':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '401':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '403':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '404':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '409':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '429':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role:
                  type: string
                  enum:
                  - owner
                  - admin
                  - editor
                  - viewer
              required:
              - role
      security:
      - session: []
      parameters:
      - name: account
        in: path
        required: true
        schema:
          type: string
      - name: actor
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/AccountSelector'
      tags:
      - Accounts
    delete:
      operationId: removeAccountMember
      summary: Remove a member without deleting account resources
      description: Owner or admin required. Templates and balance remain in the account; the removed member and their keys immediately lose authority.
      responses:
        '204':
          description: Remove a member without deleting account resources
        '400':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '401':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '403':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '404':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '409':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
        '429':
          description: Typed refusal with a stable error code.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Refusal'
      security:
      - session: []
      parameters:
      - name: account
        in: path
        required: true
        schema:
          type: string
      - name: actor
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/AccountSelector'
      tags:
      - Accounts
components:
  schemas:
    AccountMember:
      type: object
      properties:
        actor_id:
          type: string
        email:
          type: string
        role:
          type: string
          enum:
          - owner
          - admin
          - editor
          - viewer
      required:
      - actor_id
      - email
      - role
    PrepareArtRowsRequest:
      type: object
      properties:
        preset_id:
          type: string
        rows:
          type: array
          maxItems: 10
          items:
            type: object
            properties:
              dynamic_data:
                type: object
                additionalProperties:
                  type: string
              filename:
                type: string
              rows:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: object
                    additionalProperties:
                      type: string
                description: This item's rows for its repeat groups and tables (rows_key)
            additionalProperties: false
          minItems: 1
        dry_run:
          type: boolean
          default: false
      required:
      - preset_id
      - rows
      additionalProperties: false
    VariableDiagnosticCode:
      type: string
      description: The stable codes of variable diagnostics (specs/007-nested-variables/contracts/language.md). A diagnostic names the variable, the code, a reason sub-code, the referenced name, a cycle path and a code-point span in the source — never a source string, a supplied value or a result. A schema problem refuses the save (invalid_name, invalid_mode, reserved_name, unsupported_row_scope, source_limit) and nothing is written; a definition that does not resolve from the saved values is saved and named in the save's warnings; at render every unresolvable definition refuses the request before any charge (400, nothing rendered, nothing charged) with the same codes.
      enum:
      - invalid_name
      - invalid_mode
      - invalid_format
      - invalid_format_value
      - reserved_name
      - unsupported_row_scope
      - unsupported_reference_scope
      - template_syntax
      - formula_syntax
      - unknown_reference
      - cycle
      - nonnumeric_operand
      - division_by_zero
      - numeric_limit
      - source_limit
      - node_limit
      - depth_limit
      - output_limit
      - circular_layout_dependency
    PrepareArtJobRequest:
      type: object
      properties:
        job_id:
          type: string
          format: uuid
      required:
      - job_id
      additionalProperties: false
    PrepareArtRequest:
      type: object
      properties:
        preset_id:
          type: string
        rows:
          type: array
          maxItems: 10
          items:
            type: object
            properties:
              dynamic_data:
                type: object
                additionalProperties:
                  type: string
              filename:
                type: string
              rows:
                type: object
                additionalProperties:
                  type: array
                  items:
                    type: object
                    additionalProperties:
                      type: string
                description: This item's rows for its repeat groups and tables (rows_key)
            additionalProperties: false
          minItems: 1
        dry_run:
          type: boolean
          default: false
        job_id:
          type: string
          format: uuid
      additionalProperties: false
      oneOf:
      - $ref: '#/components/schemas/PrepareArtRowsRequest'
      - $ref: '#/components/schemas/PrepareArtJobRequest'
      description: Rows are the same objects as render_batch items. Send preset_id and rows to quote or start; job_id alone reads durable progress. Row indexes start at zero. Dry runs create no image/job rows, charge nothing and call no provider.
    VariableDiagnostic:
      type: object
      description: One reason a variable does not resolve (spec 007). Names, codes, positions — never a source string, a supplied value or a resolved value.
      required:
      - code
      - severity
      properties:
        code:
          $ref: '#/components/schemas/VariableDiagnosticCode'
        severity:
          type: string
          enum:
          - error
          - warning
        variable:
          type: string
          description: The definition or supplied input the problem belongs to; empty for a context-wide limit.
        reference:
          type: string
          description: The referenced name (unknown_reference, nonnumeric_operand).
        path:
          type: array
          items:
            type: string
          description: A cycle, its first name repeated at the end.
        reason:
          type: string
          description: 'A stable sub-code: which syntax rule or which limit.'
        span:
          type: object
          description: Half-open range of Unicode code points in the definition's source.
          properties:
            start:
              type: integer
            end:
              type: integer
    Account:
      type: object
      properties:
        id:
          type: string
        kind:
          type: string
          enum:
          - personal
          - team
        name:
          type: string
        role:
          type: string
          enum:
          - owner
          - admin
          - editor
          - viewer
        created_at:
          type: string
          format: date-time
      required:
      - id
      - kind
      - name
      - created_at
    Refusal:
      type: object
      description: 'Every refusal of every door (status 400 and above), on REST and as the JSON text of an MCP tool error. `error` is a stable machine code to branch on; `message` is an English sentence for the log or the agent. A door that names its condition uses its own code (preset_not_found, unknown_field, variables_unresolved, insufficient_credits, api_key_scope_insufficient, …) and adds its fields beside the two; any other refusal carries the code of its HTTP status class: 400 invalid_input (invalid_request when the body is not the JSON the door reads), 401 unauthorized / invalid_token / invalid_api_key, 403 forbidden, 404 not_found, 405 method_not_allowed (with `allow`), 408/504 timeout, 409 conflict, 413 request_too_large (with `limit_bytes`), 422 unprocessable, 429 rate_limit_exceeded, 500 internal_error, 502/503 service_unavailable. A path that does not exist answers 404 not_found and a wrong method 405 before any credential is read. The message never carries our infrastructure''s text (hosts, drivers, Go type names).'
      required:
      - error
      - message
      properties:
        error:
          type: string
          description: Machine code, snake_case.
        message:
          type: string
          description: What was refused and what to do, in English.
        fields:
          type: array
          description: 'unknown_field: each key the door does not read, with the nearest known key. Nothing was run or charged. A near miss (a typo of one or two letters, a known alias) is not refused: it is renamed and reported in the reply: `autofixes` on /render/sync, /render/async, /batch-tasks, /assets/import and /user/api-keys; `autofixed_fields` on the doors that run an MCP tool (/render/batch, /render/preview, PATCH /presets/{id}, components, theme, clone, palette).'
          items:
            type: object
            properties:
              field:
                type: string
                description: 'The key as sent, with its path: `items[0].filenme`.'
              did_you_mean:
                type: string
        diagnostics:
          type: array
          description: 'variables_unresolved: why the template''s variables do not resolve for this call. Never a source, a supplied value or a result. Absent on the public /u/ link, whose visitor is not the template''s author.'
          items:
            $ref: '#/components/schemas/VariableDiagnostic'
        prompt:
          type: string
          description: 'art_missing: the resolved art description.'
        prepare_art:
          $ref: '#/components/schemas/PrepareArtRequest'
        style_id:
          type: string
          description: An unavailable or unowned art style.
        generate_asset:
          type: object
          description: Exact cache-sharing repair for inline layouts, drafts, document masters and document-specific variable or page facts. Generate the supplied resolved prompt, then retry the render.
          properties:
            style_id:
              type: string
            prompt:
              type: string
            aspect:
              type: string
      additionalProperties: true
  parameters:
    AccountSelector:
      name: X-Rendry-Account
      in: header
      schema:
        type: string
      description: Browser/OAuth current member account selector. API keys/embed credentials are bound to their persisted account and reject another account. Omitting this header selects the browser actor personal account.
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: 'API key sk_live_... or sk_test_... — create at Settings → API Keys. Every key has a scope (read, render or full — see the APIKey schema); a call the scope does not cover answers 403 with `error` = `api_key_scope_insufficient`, the refused `tool`, the key''s `scope`, and a `message` naming what the key can call. A key limited to a list of presets answers a preset outside it with 403 `api_key_preset_not_allowed` and the refused `preset_id`; such a key renders and edits only its listed presets, and an inline design (canvas + layers, a document page or master of its own), a draft or a new template is refused with 403 `api_key_limited_to_presets` and a `reason` (inline_design, draft, create_template, inline_page). RESERVED: no door issues a key limited to presets yet — POST /user/api-keys hands out keys for the whole account — so `api_key_preset_not_allowed` and `api_key_limited_to_presets` are documented for clients built ahead of that door and are not answered by any key issued today.'
    session:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'The browser session of the signed-in owner: the JWT POST /auth/login (or the SSO door) returns, sent as `Authorization: Bearer <jwt>`. Opens every render and template door and, alone, the account cabinet (API keys, account deletion, password, billing).'
    connector:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'The token the OAuth 2.1 flow under /oauth issues to an MCP client (claude.ai connectors): the same JWT shape as a session, tagged as issued to a connector. Opens the render and template doors and /mcp; every cabinet door refuses it with 403 `browser_session_required`, account deletion with 403 `account_deletion_needs_session`.'
    embed:
      type: http
      scheme: bearer
      description: Ephemeral em_... token redeemed by the origin-restricted embedded editor. Its account, trusted subject, role and live/test mode are persisted server-side. It cannot access account administration, billing, account-wide batch services or public links. Never persist or put it in a URL.
x-rendry-service-policy:
  rates:
    rest_render:
      requests: 10
      window_seconds: 1
      burst: 10
      scope: account
      consistency: api_process
    mcp_request:
      requests: 10
      window_seconds: 1
      burst: 10
      scope: account
      consistency: api_process
    ui_request:
      requests: 10
      window_seconds: 1
      burst: 10
      scope: account
      consistency: api_process
    public_link:
      requests: 60
      window_seconds: 60
      burst: 60
      scope: ip
      consistency: api_process
    embed_frame:
      requests: 10
      window_seconds: 60
      burst: 10
      scope: ip
      consistency: api_process
    embed_redeem:
      requests: 10
      window_seconds: 60
      burst: 10
      scope: ip
      consistency: api_process
  sync_concurrency:
    account: 4
    subject: 2
    consistency: api_process
    scope: synchronous_render
  document_queue:
    pending_per_account: 4
    long_pending_per_account: 1
    long_above_pages: 20
    consistency: postgres_transaction
    scope: account; queued and processing documents
  retention:
    authenticated_days: 365
    guest_hours: 72
    url_cache_days: 30
    starts_at: 'authenticated: completion; guest: batch creation'
  end_user:
    header: X-End-User
    max_bytes: 64
    pattern: ^[A-Za-z0-9_.:@-]{1,64}$
    authority: analytics only; trusted embedded subject takes precedence
  notes:
  - REST, MCP and UI request buckets are separate; each account bucket is shared by members, keys and embedded subjects
  - API keys bypass only the UI bucket; authenticated embedded sessions use it
  - Sync concurrency is per API process; queued document admission is separately reserved in PostgreSQL
  - Retention is the source policy; deployment of storage lifecycle rules requires a separate operator action