Helm API
A versioned REST surface that lets Helm talk to the tools you already use: agency dashboards, CI, maintenance scripts, Zapier or n8n. Read the state of your fleet and trigger the main operations without opening the panel.
The contract is stable: a change that breaks existing clients is never applied to v1 — it goes into a new version.
Authentication
Every request carries the key in an Authorization header. Keys are created in Settings → API keys: you need the org:manage permission (OWNER or ADMIN role) and a plan that includes the public API.
The plaintext value is shown only once, at creation: at rest we keep just an SHA-256 hash, so not even we can recover it. To rotate a key, create a new one, update the integration, then revoke the old one.
Authorization model
A key acts on behalf of the member who created it. Effective permissions are the intersection of the scopes granted to the key and the permissions that member holds at that moment in the organization. Three practical consequences:
- a key can never do more than the person who created it;
- demoting or removing that member disables their keys instantly, with no need to revoke them by hand;
- per-site scoping is inherited: if the creator sees 3 sites out of 50, the key sees 3.
A key never inherits platform administrator privileges, even if its creator has them.
Scopes
Each key carries the scopes chosen at creation. Routes declare what they require: without it, the response is 403 MISSING_SCOPE.
Deliberately outside the public API are the operations that shouldn't happen without a person present: deleting a site, restoring a backup (it overwrites the site), 1-click login into wp-admin, team management and billing.
Rate limit
120 requests per minute per key. Every response reports the current state of the window; past the limit you get 429 with Retry-After.
Errors
Uniform shape, discriminated on the code field: that's the one to branch on in code. The message is English — the API speaks one language — and is written for developers, so it may change.
For a site out of reach the response is 404, not 403: a 403 would confirm that id exists to someone who shouldn't know it.
Endpoints
All paths are relative to https://tendfolio.com/api/v1. Where {siteId} appears, use the id returned by GET /sites.
The key's identity: organization, plan, granted scopes. This is the first endpoint to call when wiring up an integration — if it answers, key and plan are fine.
siteCountis the number of sites visible to this key, not the organization's total: if its creator sees 3 sites out of 50, it reads 3.
The sites this key can reach, with connection status, versions and pending updates.
As above for a single site, plus the full plugin and theme lists.
Only what has an update available: plugins, themes and core.
Queues updates. The response is immediate: the work continues in the worker and shows up in the site's activity log, attributed to the member who created the key.
backupFirst— back up the database before updating (requires thebackupsfeature in the plan).safeUpdate— checks the site before and after, with automatic rollback if it breaks. ImpliesbackupFirst.- An item of type
coreadditionally requires thecore:updatescope.
Latest scan and issues still open — neither fixed nor ignored.
Queues a security scan.
The last 50 backups, metadata only.
- Download tokens are never exposed by the public API.
sizeBytesis a string: a backup can exceed 2^53 bytes, past which a JSON number would lose precision.
Starts a manual backup.
typeis optional:DATABASE(default),FILESorFULL.- The plan's
backupsfeature, the monthly manual-backup quota and available storage all apply: if any is missing the response is 403 with the relevantcode.
Generates an article with AI and places it on the site as a draft, published or scheduled. Omit topicPrompt and the system picks the subject itself, from the site categories and what it has already published, avoiding duplicates.
- Asynchronous: it answers immediately with status QUEUED, generation takes one or two minutes. Follow it with GET on the same id.
- Requires the ai_content plan feature and connector ≥ 2.20.0 on the site. Credits (1/2/3/5/7 for the article depending on length, plus 3 per image) are charged on request and refunded if generation fails without placing anything on the site.
- With count up to 5 you generate several articles at once: each takes a different topic, and when topicPrompt is set the first follows it literally while the others derive distinct angles. Every article has its own credit reservation: if credits run out mid-batch, count in the response is lower than requested.
Publish, move back to draft, or schedule an article already generated
- No credits: the piece is already written and paid for. WordPress is updated first and Helm second, so the panel never says "published" while the site still shows a draft. Scheduling requires connector ≥ 2.21.0 and a future date.
- A scheduled article is published by WordPress, not by Helm. WP-Cron only fires on the first visit after the slot, so on a site without traffic it may never fire: every ten minutes Helm checks which posts are more than fifteen minutes late and publishes them, keeping their intended date. Anything moved back to draft is left alone.
Last 50 generated articles for the site, without the body text.
A single article with the full text and the generation progress.
- Steps run in order: context → topic → text → images → publish. Status goes QUEUED → RUNNING → READY, or FAILED with the error field set.
Monitoring status and the open incident, if there is one.
Operational notes
- Server-to-server. CORS stays restricted to the panel's domain: a key must never be put in browser JavaScript, where anyone opening devtools could read it.
- HTTPS only.
- Traceability. Every key records last use and last IP; creation and revocation land in the audit log, and actions started via the API appear in the activity log attributed to the member who created the key.
Ready to integrate?
Create a key in the panel and verify the integration with a call to /me.