Maileditor Docs
PluginAPI referenceEmbedded API

Bootstrap and catalog

What the plan allows and how much is left, plus the curated template gallery and module library the editor browses.

All endpoints on this page require Authorization: Bearer {session_token} from the session endpoint and the embedded headers. They are limited to 120 requests per minute per session.

Bootstrap

What this plugin's plan allows and what the plugin is configured to show, in one round trip.

GET /public/plugin/v1/bootstrap
Authorization: Bearer mep_…

curation is what the plugin is configured to expose: categories set by MailEditor, blocks, AI and stock providers set by the owner. features is what the plan includes. They are reported separately so the editor can tell "your administrator turned this off" from "your plan does not include this". Blocks are the exception: curation.blocks.enabled is already intersected with the plan.

Quotas are spent and subscriptions change during a session, so re-fetch this rather than caching it for the life of the token.

200

{
  "message": "Bootstrap retrieved successfully",
  "result": {
    "bootstrap": {
      "plugin": { "plugin_id": "9f3c…", "name": "Acme Editor", "version": "1.0.0" },
      "mode": "b",
      "tier": "development",
      "subscription": { "plan": "Free", "status": "active", "renews_at": null },
      "features": ["html_editor", "ai_generations"],
      "entitlements": [ "…every allowance…" ],
      "curation": {
        "templates": { "is_filtered": false, "categories": [] },
        "modules": { "is_filtered": false, "categories": [] },
        "blocks": { "blocks": [], "enabled": [], "hidden": [], "restricted": [], "total": 14, "is_customized": false },
        "ai": { "is_available": true, "providers": ["openai"] },
        "stock": { "is_available": true, "providers": [{ "value": "unsplash", "label": "Unsplash" }] },
        "logo": null,
        "theme": null
      },
      "quotas": [
        {
          "feature": "ai_generations",
          "name": "AI Generations (BYOK)",
          "group": "AI",
          "kind": "count",
          "is_enabled": true,
          "limit": "unlimited",
          "limit_value": null,
          "used": 120,
          "remaining": null,
          "is_unlimited": true,
          "resets_at": null
        }
      ],
      "enforced": true
    }
  }
}
FieldNotes
featuresThe feature ids the plan includes
entitlementsEvery allowance in full, including disabled ones, so you can grey out rather than hide
quotasOnly the countable allowances. A switch such as html_editor never appears here
quotas[].limitThe plan's own wording, such as "500" or "30 GB"
quotas[].limit_valueParsed, for arithmetic. Bytes for sizes. null means uncapped
subscriptionnull when the plugin is on no plan
tierproduction when the domain is verified, otherwise development
enforcedWhether requests past remaining: 0 are refused. See below
curationWhat the plugin is configured to show: the categories MailEditor set for the plugin, plus blocks, AI and stock availability, logo and theme as set in the dashboard

users counts end users who have saved work: distinct external_user_id values across the plugin's templates. Someone who never saves takes no seat, and anonymous sessions never do. image_storage counts only bytes on MailEditor storage; uploads to your own bucket are not counted. ai_generations is unlimited on every plan, because generations run on the provider key you attach.

curation

FieldMeaning
blocksThe block palette as configured on the Basic Block Management tab
blocks.enabledAlready intersected with the plan. Render exactly these
blocks.blocksEvery block with is_enabled (owner), is_entitled (plan) and is_available (both)
templates.categories, modules.categoriesThe categories configured for the plugin, in order
is_filteredfalse means no selection, so every category is available and categories is []. Branch on is_filtered, not on the array being empty
ai.is_availableWhether this plugin has an AI provider key
ai.providersWhich providers are configured. Names only
stock.is_availableWhether this plugin has any stock provider key. false means the editor shows no stock library
stock.providersThe providers to offer, each { value, label }. Pass value as provider on the stock endpoints
logoThe owner's logo object, or null
themeThe owner's editor theme as { primary, secondary, foreground, background, font }. The colors are hex strings or null; font is a Google Fonts family name or null. null when nothing is set

enforced

true means a request past remaining: 0 returns 402, and a plugin with no active subscription is entitled to nothing. When it is false, usage is reported but nothing is refused. Read this field rather than assuming.

Catalog

The following endpoints browse the template gallery and module library, narrowed to the categories configured for the plugin.

  • Filters narrow, never widen. Naming a category the plugin has not selected returns nothing.
  • result.filters lists only curated categories, so the editor never renders a facet that yields an empty list.

The editor calls these modules; the API paths use components.

The gallery endpoints require the template_gallery_access plan feature and the component endpoints require module_library. Without the feature they return 402 feature_not_in_plan, and the editor disables the corresponding start option or sidebar tab.

GET /public/plugin/v1/templates?search=launch&category=Product&per_page=15
QueryNotes
searchMatches template name
category, industry, seasonBy name. All clears. Always intersected with the plugin's curation
typepremium or free
sort_by, per_pageDefault 15 per page

200

{
  "message": "Template Fetch Successfully",
  "result": {
    "templates": {
      "data": [
        {
          "id": 41,
          "name": "Product Launch",
          "slug": "product-launch",
          "description": null,
          "meta_description": null,
          "is_premium": false,
          "thumbnail": "https://…",
          "thumbnail_mobile": "https://…",
          "created_at": "2026-08-13T09:14:22.000000Z",
          "avg_rating": 4.5,
          "rating_count": 12,
          "categories": [{ "id": 3, "name": "Product", "slug": "product" }],
          "industries": [],
          "tags": []
        }
      ],
      "links": { "first": "…", "last": "…", "prev": null, "next": null },
      "meta": { "current_page": 1, "per_page": 15, "total": 1 }
    },
    "filters": { "categories": ["All", "Product"] }
  }
}

Premium templates are listed and flagged with is_premium rather than hidden.

Browse the component library

GET /public/plugin/v1/components?category=Checkout&per_page=10

200. total_count is the plugin's visible total. Module HTML is inlined.

{
  "message": "Components retrieved successfully",
  "result": {
    "total_count": 8,
    "components": {
      "data": [
        {
          "id": 7,
          "name": "Cart Summary",
          "thumbnail": "https://…",
          "is_featured": false,
          "html": "<table>…</table>",
          "css": null,
          "category": [{ "id": 4, "name": "Checkout", "slug": "checkout" }]
        }
      ],
      "links": {},
      "meta": {}
    },
    "filters": { "category": ["Featured", "Checkout"] }
  }
}

Template categories

GET /public/plugin/v1/template-categories

Returns the owner's selection when the plugin is curated, otherwise every category.

{
  "message": "Template categories retrieved successfully",
  "result": {
    "categories": [
      { "id": 3, "name": "Product", "slug": "product", "description": null, "templates_count": 12 }
    ]
  }
}

templates_count is what that category will yield. A selected but empty category is still returned with a count of 0.

Component categories

GET /public/plugin/v1/component-categories

200 with counts scoped to the plugin:

{
  "message": "Categories fetched successfully",
  "result": {
    "all_components_count": 8,
    "features_components_count": 2,
    "categories": [
      { "id": 4, "name": "Checkout", "slug": null, "components_count": 8, "class": "ComponentCategory", "meta_title": null, "meta_description": null, "description": null }
    ]
  }
}

On this page