sendraven-ai Templates API

The Templates API from sendraven-ai — 4 operation(s) for templates.

Operations 6

GET /v1/templates List templates and their required variables #
POST /v1/templates Create or update a template #
GET /v1/templates/{slug} Retrieve a template #
DELETE /v1/templates/{slug} Delete a template #
POST /v1/templates/{slug}/render Render a template without sending #
POST /v1/templates/{slug}/duplicate Duplicate a template #

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/sendraven-ai:sendraven-ai-templates-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

sendraven-ai-templates-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Sendraven Ai Templates API
  version: 1.0.0
  description: 'Operations tagged Templates across 2 of this provider''s published API definitions: sendraven-ai-api-openapi.json, sendraven-ai-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.sendraven.ai
security:
- bearerAuth: []
tags:
- name: Templates
paths:
  /v1/templates:
    get:
      summary: List templates and their required variables
      description: 'Every template, sorted by name, each with variables: the placeholder names a render or send must supply. Not paged (cap 500).'
      x-required-scope: templates:read
      responses:
        '200':
          description: Templates.
          content:
            application/json:
              schema:
                type: object
                required:
                - object
                - data
                - has_more
                - next_cursor
                properties:
                  object:
                    type: string
                    enum:
                    - list
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Template'
                  has_more:
                    type: boolean
                    description: 'Not paged: true only when the list hit its cap, meaning there is more than this endpoint can return.'
                  next_cursor:
                    type:
                    - string
                    - 'null'
                    description: Always null; this list is not paged.
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:read scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Templates
      operationId: getV1Templates
      x-operation-id-source: derived
    post:
      summary: Create or update a template
      description: 'Creates the template, or updates the one with this slug (201 new, 200 updated); variables is recomputed from the copy either way. On an update name, subject and html are replaced; text is replaced when given as a string, kept when left out, and removed when null; "" is refused with 422 (send null). Placeholders are {{name}}: letters, digits, underscores and dots (a dot is part of the name, not a path). Values are HTML-escaped into html and go into subject and text as given. Changing a template changes every later send that uses it, including automation steps already scheduled; a new placeholder makes those steps fail unless enrolments carry a value.'
      x-required-scope: templates:write
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - slug
              - name
              - subject
              - html
              properties:
                slug:
                  type: string
                  pattern: ^[a-z0-9-]+$
                  description: Lower-case letters, digits and hyphens.
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                subject:
                  type: string
                  minLength: 1
                  maxLength: 998
                  description: May contain placeholders.
                html:
                  type: string
                  minLength: 1
                  description: May contain placeholders.
                text:
                  type:
                  - string
                  - 'null'
                  minLength: 1
                  description: Plain-text body. May contain placeholders. On an update, left out keeps the stored one and null removes it. An empty string is refused.
      responses:
        '200':
          description: 'Updated: the stored template, with updated_at set.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
        '201':
          description: Created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
        '400':
          description: 'invalid_json: the request body is not valid JSON.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:write scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'idempotency_in_progress: a request with the same Idempotency-Key was still running on this path after waiting up to 8 seconds for it (a retry that finds it finished receives its response instead). Retry after a short wait.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: 'payload_too_large: the body is larger than this endpoint accepts (5 MB unless stated).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: 'invalid_request: text is an empty string (the message says to send null to remove the text body), or the body failed validation (details lists each field). Also idempotency_key_reused: this Idempotency-Key was already used on this path with a different request body (checked right after the scope, so a credential without the scope gets 403 instead, and answered at once even while the first request is still running). Do not retry; send the new request under a new key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      parameters:
      - name: Idempotency-Key
        in: header
        schema:
          type: string
        description: 'Replaying the same key on the same path in this workspace within 24 hours returns the stored response, with an Idempotent-Replay: true header, instead of acting again. Only successful responses are stored, so a failed request can be fixed and retried under the same key. The body is compared (key order ignored): the same key with a different body is 422 idempotency_key_reused, so use a new key for every new request. Use an unguessable value such as a UUID.'
      tags:
      - Templates
      operationId: postV1Templates
      x-operation-id-source: derived
    servers:
    - url: https://api.sendraven.ai
  /v1/templates/{slug}:
    get:
      summary: Retrieve a template
      description: One template by slug, with its variables.
      x-required-scope: templates:read
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
        description: The template's slug. Templates are addressed by slug, never by id.
      responses:
        '200':
          description: The template.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:read scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: 'not_found: no template with this slug in the workspace.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Templates
      operationId: getV1TemplatesBySlug
      x-operation-id-source: derived
    delete:
      summary: Delete a template
      description: Deletes the template. Refused with 409 while an active or paused automation has a step using it (the message lists them), so a live sequence cannot lose a step's body; delete those automations or set them to draft first. Campaigns carry their own html and never block it. Once deleted, a later send naming it is refused, and a draft automation step naming it fails each enrolment that reaches it after the automation is activated.
      x-required-scope: templates:write
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
        description: The template's slug. Templates are addressed by slug, never by id.
      responses:
        '200':
          description: Deleted.
          content:
            application/json:
              schema:
                type: object
                required:
                - slug
                - deleted
                properties:
                  slug:
                    type: string
                  deleted:
                    type: boolean
                    enum:
                    - true
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:write scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: 'not_found: no template with this slug in the workspace, or it was deleted by another request meanwhile.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'invalid_state: an active or paused automation still uses the template; the message names each one. Nothing was deleted. Retrying will not help until those automations are deleted or set to draft.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Templates
      operationId: deleteV1TemplatesBySlug
      x-operation-id-source: derived
    servers:
    - url: https://api.sendraven.ai
  /v1/templates/{slug}/render:
    post:
      summary: Render a template without sending
      description: 'Check the copy reads correctly before mailing a real person. Follows the send rules exactly: values are HTML-escaped into html, and every name in the template''s variables must have a value. An empty string counts as a value; a missing key or null does not. Nothing is sent or stored.'
      x-required-scope: templates:read
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
        description: The template's slug. Templates are addressed by slug, never by id.
      - name: Idempotency-Key
        in: header
        schema:
          type: string
        description: 'Replaying the same key on the same path in this workspace within 24 hours returns the stored response, with an Idempotent-Replay: true header, instead of acting again. Only successful responses are stored, so a failed request can be fixed and retried under the same key. The body is compared (key order ignored): the same key with a different body is 422 idempotency_key_reused, so use a new key for every new request. Use an unguessable value such as a UUID.'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                variables:
                  type: object
                  default: {}
                  additionalProperties:
                    oneOf:
                    - type: string
                    - type: number
                    - type: boolean
                    - type: 'null'
                  description: Placeholder name to value. Numbers and booleans become their string form; null counts as no value; an object or array is refused. Names the template does not use are ignored.
      responses:
        '200':
          description: The rendered subject and bodies.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TemplateRenderResult'
        '400':
          description: 'invalid_json: the request body is not valid JSON.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:read scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: 'not_found: no template with this slug in the workspace.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'idempotency_in_progress: a request with the same Idempotency-Key was still running on this path after waiting up to 8 seconds for it (a retry that finds it finished receives its response instead). Retry after a short wait.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: 'payload_too_large: the body is larger than this endpoint accepts (5 MB unless stated).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: 'missing_variables: one or more of the template''s variables has no value; the error carries missing, the names. invalid_request: variables is not an object, or a value is an object or array (the message names it, e.g. variables.plan). Also idempotency_key_reused: this Idempotency-Key was already used on this path with a different request body (checked right after the scope, so a credential without the scope gets 403 instead, and answered at once even while the first request is still running). Do not retry; send the new request under a new key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Templates
      operationId: postV1TemplatesBySlugRender
      x-operation-id-source: derived
    servers:
    - url: https://api.sendraven.ai
  /v1/templates/{slug}/duplicate:
    post:
      summary: Duplicate a template
      description: Copies subject, html and text under a new slug, as an independent template with its own id and created_at. The source is looked up before the body is validated.
      x-required-scope: templates:write
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
        description: The slug of the template to copy.
      - name: Idempotency-Key
        in: header
        schema:
          type: string
        description: 'Replaying the same key on the same path in this workspace within 24 hours returns the stored response, with an Idempotent-Replay: true header, instead of acting again. Only successful responses are stored, so a failed request can be fixed and retried under the same key. The body is compared (key order ignored): the same key with a different body is 422 idempotency_key_reused, so use a new key for every new request. Use an unguessable value such as a UUID.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - slug
              properties:
                slug:
                  type: string
                  pattern: ^[a-z0-9-]+$
                  description: The new template's slug; must be unused in the workspace.
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: Trimmed, then 1 to 200 characters; an empty or whitespace-only name is 422. Left out, it is the source's name followed by " copy".
      responses:
        '201':
          description: The copy.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Template'
        '400':
          description: 'invalid_json: the request body is not valid JSON.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: 'unauthorized: no Bearer token, or the key or token is invalid, revoked or expired.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: 'forbidden: the key lacks the templates:write scope. The message names it.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: 'not_found: no template with the source slug in the workspace.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: 'conflict: a template with the new slug already exists. Pick another slug; retrying the same one will not help. Also idempotency_in_progress: a request with the same Idempotency-Key was still running on this path after waiting up to 8 seconds for it (a retry that finds it finished receives its response instead). Retry after a short wait.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '413':
          description: 'payload_too_large: the body is larger than this endpoint accepts (5 MB unless stated).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: 'invalid_request: slug missing or not lower-case letters, digits and hyphens, or name empty (after trimming) or over 200 characters. The message names each field and details lists them. Also idempotency_key_reused: this Idempotency-Key was already used on this path with a different request body (checked right after the scope, so a credential without the scope gets 403 instead, and answered at once even while the first request is still running). Do not retry; send the new request under a new key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: 'rate_limited: more requests than the per-key rate (600 a minute by default). Wait the seconds in the Retry-After header and retry.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: 'service_unavailable: the API is under heavy load and could not get a database connection in time. Usually nothing was done; a send that was already under way may have been, so check GET /v1/emails before retrying one. Wait the seconds in the Retry-After header.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      tags:
      - Templates
      operationId: postV1TemplatesBySlugDuplicate
      x-operation-id-source: derived
    servers:
    - url: https://api.sendraven.ai
components:
  schemas:
    Error:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - type
          - message
          properties:
            type:
              type: string
              description: 'Stable and safe to branch on, and the same status on every route: invalid_request (422), invalid_json (400), payload_too_large (413), unauthorized (401), forbidden (403), not_found (404), conflict (409, an identifier already taken), invalid_state (409, the resource''s current state does not allow this), plan_limit_reached (402), payment_method_required (402), billing_past_due (402), budget_exceeded (402), no_verified_identity (422), missing_variables (422), unknown_topic (422), idempotency_in_progress (409), idempotency_key_reused (422), approval_in_progress (409), rate_limited (429), daily_limit (429), recipient_not_allowed (403), invalid_schedule (422), warmup_limit (422), no_postal_address (422), workspace_suspended (422), gone (410), ses_error (502), internal_error (500), service_unavailable (503).'
            message:
              type: string
              description: For people; may change.
            details:
              type: array
              items:
                type: object
                additionalProperties: true
              description: 'On many 422 invalid_request answers: one entry per field that failed validation.'
            missing:
              type: array
              items:
                type: string
              description: 'Only on missing_variables, and always there: the names of the template variables that were not supplied.'
    TemplateRenderResult:
      type: object
      required:
      - subject
      - html
      - text
      properties:
        subject:
          type: string
          description: Values substituted as given (the subject is not HTML).
        html:
          type: string
          description: Values HTML-escaped on substitution.
        text:
          type:
          - string
          - 'null'
          description: null when the template has no text body. Values substituted as given.
    Template:
      type: object
      description: A template. Every field is always present, null when it has no value.
      required:
      - id
      - slug
      - name
      - subject
      - html
      - text
      - variables
      - created_at
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Not used by any endpoint; templates are addressed by slug.
        slug:
          type: string
          pattern: ^[a-z0-9-]+$
          description: Unique within the workspace.
        name:
          type: string
        subject:
          type: string
          description: The subject line, with {{name}} placeholders.
        html:
          type: string
          description: The HTML body, with placeholders. Values substituted here are HTML-escaped.
        text:
          type:
          - string
          - 'null'
          description: The plain-text body; null when the template has none. An empty string counts as no text body when rendering.
        variables:
          type: array
          items:
            type: string
          description: Every placeholder name in the subject and both bodies, sorted, without duplicates. All are required to render or send.
        created_at:
          type: string
          format: date-time
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
          description: null until the template is first updated.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An API key of the form sk_live_…, created at /developers, or an OAuth access token (srv_oat_…). An OAuth token carries its grant's scopes but none of an API key's guardrails, and cannot decide approvals.
x-refined-from:
- sendraven-ai-api-openapi.json
- sendraven-ai-openapi.json