Skip to content

Early-bird lifetime licence: $199 once, for the first 200 buyers only. See the offer

All docs

REST API

Snipfire's editor runs on a REST API that you can use too: from deploy scripts, CI, or your own tools.

Base URL: https://example.com/wp-json/snipfire/v1/

Snipfire's routes never run your snippets, so a broken snippet can't block the API.

Authentication

Use any authentication WordPress's REST API accepts:

  • Application passwords (built into WordPress: Users → Profile → Application Passwords) with HTTP Basic authentication. Best for scripts.

    curl -u 'jane:abcd efgh ijkl mnop qrst uvwx' https://example.com/wp-json/snipfire/v1/snippets
  • Cookies and a nonce, from JavaScript running in the WordPress admin: send the X-WP-Nonce header with a wp_rest nonce.

Permission levels

Each route needs one of three team access levels. Without Snipfire Pro, only administrators have access (all levels).

Level Routes
view Reading: snippets, history, schema, export, activity
design Changing snippets. Each change is also checked against the user's level, for the snippet as it is and as it would be (a designer can't create PHP, for example)
full Imports, folder renames, settings, Git sync, preview links

A refused change returns 403 with the reason in message.

Snippets

Method and route Level What it does
GET /snippets view All snippets, without code. ?with_code=1 includes the code
POST /snippets design Create a snippet (body: snippet fields)
GET /snippets/{id} view One snippet, with code
PUT / PATCH / POST /snippets/{id} design Update; only the fields you send change
DELETE /snippets/{id} design Delete
POST /snippets/{id}/enable design Switch on (checks and test-loads)
POST /snippets/{id}/disable design Switch off
POST /snippets/{id}/run design Run a PHP or HTML snippet once; returns { "output": "…", "error": null }
POST /snippets/{id}/duplicate design Copy (switched off); returns the copy, 201
POST /snippets/{id}/editing design Check in while the snippet is open: returns others (who else has it open), modified, modified_by and by_name (who saved it last)
DELETE /snippets/{id}/editing design Check out when you close the snippet
POST /validate design Check a snippet without saving (body: snippet fields); returns { "errors": [], "warnings": [] }

Create, update, enable and disable return:

{
  "snippet": { "id": 12, "title": "…", "status": "active", "code": "…" },
  "errors": [],
  "warnings": [],
  "deactivated": false
}

Status 201 for a new snippet, 200 for an update, 400 when it couldn't be saved at all. A snippet that was saved but has problems is returned with errors (each { "message": "…", "line": 3 }) and switched off; deactivated is true when you asked for it to be on and it isn't.

Example: create a CSS snippet and switch it on:

curl -u "$USER:$APP_PASSWORD" -X POST https://example.com/wp-json/snipfire/v1/snippets \
  -H 'Content-Type: application/json' \
  -d '{"title":"Hide store notice","type":"css","code":".woocommerce-store-notice{display:none}","status":"active"}'

Saving over someone else's changes

To avoid overwriting a change someone else made after you loaded a snippet, send the snippet's modified value (as you loaded it) as base_modified with an update:

{ "code": "…", "base_modified": 1790000000 }

If someone else has saved the snippet since, the update is refused with 409 and nothing changes:

{
  "snippet": null,
  "errors": [ { "message": "Maria saved this snippet at 14:32, after you opened it. Saving now would overwrite their changes.", "line": 0 } ],
  "warnings": [],
  "deactivated": false,
  "conflict": { "user": 7, "name": "Maria", "time": 1790000100 }
}

To save anyway, send the update again with "force": true. Updates without base_modified aren't checked. The editor does this for you: see When someone else has the snippet open.

History

Method and route Level What it does
GET /snippets/{id}/revisions view Earlier versions, newest first, with who saved each
GET /snippets/{id}/revisions/{rev} view One version, with code and settings
POST /snippets/{id}/revisions/{rev}/restore design Restore it (checked and test-loaded; the current version is kept)

Bulk actions and folders

POST /bulk (design):

{ "ids": [12, 15, 18], "action": "enable", "value": "" }

Actions: enable, disable, delete, move (value = folder, "" for none), tag and untag (value = tag). Returns done (IDs), errors (ID → message) and items (the updated list). Enabling several snippets runs one test load.

POST /folders/rename (full): { "from": "Old/Name", "to": "New/Name" }. Subfolders move too. Returns { "moved": 4 }.

Export and import

Method and route Level What it does
GET /export view Export file of all snippets, or ?ids=12,15
POST /import full Import an export file (the JSON as the body). Arrives switched off unless ?keep_status=1. Returns { "created": [ids], "errors": [] }

Snippet library

Method and route Level What it does
GET /library view The snippet library: packs, and items with their code and this site's state (new, current, changed, update), snippet id, status, missing plugins and needs_edit
POST /library/install design Install. Body: slugs (list) and/or pack (pack ID), activate (true to switch them on after the checks and one test load). Returns installed (slug → ID), activated, skipped and errors (slug → reason)
POST /library/update design Update installed snippets to the library's version. Body: slugs, or "all": true. Returns updated, kept (slug → settings kept), replaced (slugs whose code edits were replaced), skipped, errors

Each snippet is checked against the user's access, so a designer's request skips PHP snippets.

Importers (other plugins)

Method and route Level What it does
GET /import/sources full Plugins with snippets to import
GET /import/sources/{source} full Preview: each snippet, how it maps, notes, Check first
POST /import/sources/{source}/run full Import. Body: ids (the other plugin's IDs; all if left out), update (re-import changed ones)
POST /import/sources/{source}/switch full Switch snippets off in the other plugin. Body: ids. Returns the Snipfire IDs to switch on next

Switching over is two requests on purpose: call switch, then switch the returned IDs on with POST /bulk ("action": "enable") in a new request, so no function is declared twice. Sources: wpcode, code-snippets, fluent-snippets, hfcm, custom-css-js, post-snippets, woody, customizer-css, wpcodebox.

WordPress abilities

Snipfire also registers WordPress abilities (WordPress 6.9+), for AI assistants and tools that use the Abilities API. See AI assistants and WordPress abilities.

Schema

GET /schema (view) returns what the editor needs to build its forms: condition types with their operators and options, the picker groups, the locations per type with their stage, the snippet types and CSS languages. Useful to build a UI or validate input.

Activity log Pro

GET /activity (view): newest first, 50 per page.

Query: snippet (ID), user (ID), action (see log actions), search, page.

Returns { "items": [...], "more": true, "actions": { "created": "Created", ... } }.

Testing mode Pro

POST /preview/new-key (full): make a new preview link; old links stop working. Returns { "url": "https://example.com/?snipfire-preview=…" }.

Git sync Agency

Method and route Level What it does
GET /git full Settings (without the token), last sync, conflicts
POST /git/settings full Change settings: provider, repo, branch, root, scope, token, api, schedule. Only the fields you send change
POST /git/check full Test the connection: { "ok": true, "message": "Connected to …" }
POST /git/sync full Sync now. Optional body { "resolve": { "<uid>": "site" \| "git" } } settles conflicts first. Returns report plus the status
POST /git/webhook none (signed) For GitHub and GitLab webhooks; see Webhooks

The token is write-only: it's never returned.

Something unclear or missing? Tell us