Skip to content

API

Public API access

Call Project Command with an API key. This page lists each open endpoint, the fields you can send, and a copy-ready example. Base URL: https://projectcommand.reversal.org. Machine-readable catalog: https://projectcommand.reversal.org/api/v1/docs/. Mint a changelog key at Changelog keys after you sign in.

API keys

Send the key on X-Api-Key or Authorization: Bearer. Examples use placeholders. This page never prints a live key.

Changelog key cpcl_

X-Api-Key: cpcl_your_key

Authorization: Bearer cpcl_your_key

One company, one venture, or one project. A company key can write that company and the ventures and projects under it.

Staff mint this at /changelog/keys/. The raw value is shown once and is not stored in the page.

Pixel key eepx_

X-Api-Key: eepx_your_key

Authorization: Bearer eepx_your_key

One tracking pixel. The key is flagged read, write, or both.

Staff create it on the pixel. Use a write key for server events and a read key for recent hit rows.

Chat widget key cpcw_

X-Api-Key: cpcw_your_key

This key is publishable. It only accepts action=config and action=message.

One site chat. Do not send a cpcl_ key from a public page.

Staff create it on Lead Connector at /chat/.

No key none

Omit X-Api-Key

Health, a public analytics card, contact notes, and console error reports.

These calls do not accept an inbox, a subject, or an HTML body from the browser.

A honeypot field named website on contact is ignored.

Ship log

POST https://projectcommand.reversal.org/api/v1/changelog/ cpcl_

Write one changelog row inside the key scope. The same external_ref returns the existing row.

FieldWhat can pass
title Required. 3 to 200 characters.
summary Required. 3 to 4000 characters.
categories feature, bugfix, improvement, security, api, ui, database, payment, workflow, docs, backup. One string or a list. category is accepted too.
priority low, medium, high, or critical. Default medium.
status completed, in_progress, or planned. Default completed.
project_id Integer. Required when the key is company-wide and you are writing a project. A project key ignores a different id.
venture_id Integer. Use this when a company key writes a venture and not a project.
organization_id Integer. A company key already locks this.
external_ref Optional idempotency id, up to 191 characters. id is accepted as the same field.
files Optional list of paths, or one comma-separated string. Each path is cut at 240 characters.
extra_notes Optional text up to 16000 characters. A key cannot PATCH this later.
author Optional. Defaults to the key name.
work_started_at Optional Eastern wall clock YYYY-MM-DD HH:MM:SS, or an ISO time.
work_ended_at Optional. Same shape as work_started_at. started_at and ended_at are accepted.
ai_duration_seconds Optional integer. ai_duration_minutes is accepted and converted.
human_estimate_seconds Optional integer. human_estimate_minutes and human_minutes are accepted.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/changelog/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"title":"Ship the public docs","summary":"Added the API access page with request examples.","categories":["docs"],"priority":"medium","external_ref":"docs-public-api-1"}'

Response

{
  "success": true,
  "code": "OK",
  "message": "Logged",
  "data": { "entry": { "title": "Ship the public docs" }, "duplicate": false }
}

Read the ship log

GET https://projectcommand.reversal.org/api/v1/changelog/ cpcl_

List entries inside the key scope. Query can narrow a company key. A project key stays on that project.

FieldWhat can pass
project_id Optional integer query. Must sit under the key.
venture_id Optional integer query.
organization_id Optional integer query.
q Optional search on title, summary, and extra notes.
limit 1 to 100. Default 20.
offset Integer. Default 0.

Example

curl "https://projectcommand.reversal.org/api/v1/changelog/?limit=20" \
  -H "X-Api-Key: cpcl_your_key"

Response

{
  "success": true,
  "data": { "entries": [] },
  "meta": { "total": 0, "limit": 20, "offset": 0 }
}

Bug report

POST https://projectcommand.reversal.org/api/v1/bugs/ cpcl_

File a bug on a project the key covers. Sending fix with the create marks it fixed and does not alert Marvis.

FieldWhat can pass
project_id Integer, or use project_slug. Must match the key scope.
project_slug Optional slug when you do not send project_id.
title Short name of the bug.
problem What is wrong. details is the longer original note.
details Optional longer description.
severity low, medium, high, or critical.
page_url Optional page. page_urls accepts a list.
fix Optional patch note. When present, the row is stored as fixed.
fix_files Optional list of file paths.
reporter_name Optional label. Do not send an email address.
status Optional. PATCH can set status or severity later.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/bugs/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"project_slug":"commandprojects","title":"Docs page 404","problem":"/documentation/ was not a route.","severity":"medium","page_url":"https://projectcommand.reversal.org/documentation/"}'

Response

{
  "success": true,
  "data": { "id": 1, "status": "open" }
}

Alert

POST https://projectcommand.reversal.org/api/v1/alerts/ cpcl_

Write an alert for one project. If message is omitted, the saved message for that page_url is used.

FieldWhat can pass
project_id Integer, or project_slug.
project_slug Optional slug.
title Short alert title.
message Optional. {page_url} and {link_url} are replaced when a template exists.
page_url Page the alert is about.
link_url Optional related URL.
severity low, medium, high, or critical.
reporter_name Optional label. Do not send an email.
status PATCH accepts open or closed.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/alerts/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"project_slug":"commandprojects","title":"Docs route missing","message":"The public API page returned 404.","severity":"medium","page_url":"https://projectcommand.reversal.org/documentation/"}'

Response

{
  "success": true,
  "data": { "id": 1 }
}

Payment

POST https://projectcommand.reversal.org/api/v1/financials/?action=payment cpcl_

Record one USD payment on a venture the key covers. The same source plus external_id returns the existing row.

FieldWhat can pass
action Query value payment. Required for this call.
amount Dollars, greater than zero. amount_cents is accepted as an integer.
source Required label such as stripe or paypal. Letters and numbers, stored as a short slug.
external_id Optional idempotency id. Letters, numbers, and . _ : - up to 80 characters.
venture_id Integer or 16-character public id. A project key fills this from the project.
project_id Required when the venture has more than one project.
paid_on Optional YYYY-MM-DD. Default is today in US Eastern. start_on is accepted.
name Optional line label.
notes Optional note. Do not send a card number or an email.
currency usd only. Other currencies are rejected.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/financials/?action=payment" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"venture_id":"12","project_id":"34","amount":"49.00","source":"stripe","external_id":"pi_example_1","paid_on":"2026-10-15","name":"October plan"}'

Response

{
  "success": true,
  "data": { "id": 1, "created": true, "venture_id": 12, "project_id": 34 }
}

Mindfile

GET https://projectcommand.reversal.org/api/v1/mindfiles/ cpcl_

Read the company or project mindfile the key is allowed to see. POST action=save writes operator notes.

FieldWhat can pass
organization_id GET query. Company mindfile. A venture key only sees its venture.
project_id GET query. Project mindfile. A project key only sees its project.
action POST save stores notes. refresh is a signed-in operator only.
positioning POST save. Optional text.
audience POST save. Optional text.
offer POST save. Optional text.
voice POST save. Optional text.
proof POST save. Optional text.
competitors POST save. Optional text.
notes POST save. Optional text.
facts POST save. Optional structured notes.

Example

curl "https://projectcommand.reversal.org/api/v1/mindfiles/?project_id=34" \
  -H "X-Api-Key: cpcl_your_key"

Response

{
  "success": true,
  "data": { "kind": "project", "brandkit": {}, "intelligence": {}, "signals": {}, "money": {} }
}

Draft agreement pack

POST https://projectcommand.reversal.org/api/v1/documents/ cpcl_

Store draft agreement PDFs on a project the key covers. Drafts are not signed contracts.

FieldWhat can pass
action pack writes the catalog. push writes one agreement_key. upload stores a PDF you already built.
project_id Required integer inside the key scope.
agreement_key Required for action=push.
title Optional label for action=upload.
label Optional label.
pdf_base64 Required for action=upload. The PDF bytes, base64.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/documents/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"action":"pack","project_id":34}'

Response

{
  "success": true,
  "data": { "project_id": 34, "stored": [] }
}

CodeShare note

POST https://projectcommand.reversal.org/api/v1/pastes/ cpcl_

Post a note through a project that already has a CodeShare binding. Binding the pvsk_ key is a staff session.

FieldWhat can pass
action note or ping. bind and unbind stay on a staff session.
project_id Required integer inside the key scope.
title Note title.
body Note text.
external_id Optional id so a repeat post can be recognized.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/pastes/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcl_your_key" \
  -d '{"action":"note","project_id":34,"title":"Ship note","body":"Public API page is live.","external_id":"note-1"}'

Response

{
  "success": true,
  "data": { "paste": { "title": "Ship note" } }
}

Site chat message

POST https://projectcommand.reversal.org/api/v1/chat/ cpcw_

The publishable widget key accepts config and message only. A cpcl_ key is for staff actions such as save and list.

FieldWhat can pass
action config or message for cpcw_. save, list, inbox, master, rotate, and status need a staff session or cpcl_ key.
name Visitor name on action=message.
phone Optional phone.
email Visitor inbox on action=message. The server uses it for the lead. Do not send a different recipient.
message What the visitor wrote.
consent Consent flag for the lead.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/chat/" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: cpcw_your_key" \
  -d '{"action":"message","name":"Avery","email":"[email protected]","message":"I want a walkthrough.","consent":1}'

Response

{
  "success": true,
  "data": { "accepted": true, "thank_you": "Thanks. We have the note." }
}

Pixel collect

POST https://projectcommand.reversal.org/api/v1/collect/ eepx_

Browser pixels can post without a key. A server event should send a write key for that pixel.

FieldWhat can pass
id Query. Public pixel id (px_ plus 16 hex). pixel_id and p are accepted.
event Optional event name.
path Optional path on the site.
referrer Optional referrer URL.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/collect/?id=px_your_pixel" \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: eepx_your_key" \
  -d '{"event":"page","path":"/pricing/","referrer":"https://example.com/"}'

Response

{
  "success": true,
  "data": { "accepted": true }
}

Contact note

POST https://projectcommand.reversal.org/api/v1/contact/ none

Public note for one project. Staff GET is a session. The browser cannot choose the recipient.

FieldWhat can pass
channel venture, helpdesk, or job. job also needs job_id on that project.
project_slug Project slug, or send project_id.
project_id Optional integer.
job_id Required when channel is job.
name Sender name.
email Sender inbox. Stored for the owner note.
message The note.
page_url Optional page they wrote from.
website Honeypot. Leave it empty. A filled value is ignored.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/contact/" \
  -H "Content-Type: application/json" \
  -d '{"channel":"venture","project_slug":"commandprojects","name":"Avery","email":"[email protected]","message":"Question about the API key.","page_url":"https://projectcommand.reversal.org/documentation/"}'

Response

{
  "success": true,
  "data": { "id": 1 }
}

Console error

POST https://projectcommand.reversal.org/api/v1/errors/ none

Store the page, what was tried, and why. Clearing the log needs a staff session.

FieldWhat can pass
project_slug Project slug, or project_id.
page_url Page that failed.
tried What the page tried to do.
reason Why it failed. Do not send a stack with secrets.

Example

curl -X POST "https://projectcommand.reversal.org/api/v1/errors/" \
  -H "Content-Type: application/json" \
  -d '{"project_slug":"commandprojects","page_url":"https://projectcommand.reversal.org/documentation/","tried":"load API docs","reason":"route was missing"}'

Response

{
  "success": true,
  "data": { "id": 1 }
}

More endpoints

These also accept a key or no key. Staff-only session routes are listed in the machine-readable catalog at /api/v1/docs/.

GET https://projectcommand.reversal.org/api/v1/health/ none

Returns csrf when a staff session is present.

GET https://projectcommand.reversal.org/api/v1/docs/ none

Documentation layer: features, snap-ins, and this endpoint catalog.

POST https://projectcommand.reversal.org/api/v1/financials/ cpcl_ key, API key, or session

Query: action=payment

Body: venture_id, amount, source, external_id, paid_on, project_id, name, notes, currency

action=payment. Header X-Api-Key. A cpcl_ key only writes its company, venture, or project. Same source + external_id returns the existing row. USD only. One project is chosen when the venture has a single project.

GET https://projectcommand.reversal.org/api/v1/jobs/ session|pixel_key

Query: limit, offset, status, project_id

Staff list item includes cost, sell, margin.

GET https://projectcommand.reversal.org/api/v1/jobs/{id}/ session|pixel_key

GET https://projectcommand.reversal.org/api/v1/jobs/{id}/customer/ session|pixel_key

Query: view=customer

Customer-safe payload.

POST|PATCH https://projectcommand.reversal.org/api/v1/jobs/ session|pixel_key

Query: id on PATCH

Body: title, client_label, project_id, status, source

GET|POST|PATCH https://projectcommand.reversal.org/api/v1/alert-urls/ session|api_key|cpcl_

Query: project_id, project_slug, venture_id, organization_id, company_id, page_url, id, limit, offset

Body: project_id, project_slug, page_url, link_url, message, status

One custom message per page URL on a project. link_url is the URL tied to that page. POST again for the same page_url updates the row. PATCH status is active or paused.

GET|POST|PATCH|DELETE https://projectcommand.reversal.org/api/v1/pixels/ session|pixel_key

Query: id, app_slug, owner_user_ref, project_id, action, key_id

Body: name, app_slug, owner_user_ref, status, project_id, allowed_hosts

Manage EE tracking pixels and eepx_ keys. POST with only project_id fills name/slug from that Command project.

GET https://projectcommand.reversal.org/api/v1/traffic/ session|pixel_key read

Query: pixel|pixel_id|id, range=24h|7d|30d, view=summary|hits

Staff traffic reports. Use analytics for public embed numbers.

GET https://projectcommand.reversal.org/api/v1/analytics/ none|pixel_key read|session for portfolio

Query: pixel px_... or app=rcna, view=card|report, range=24h|7d|30d

CORS * callable pack. Compact card by default. view=report adds hours, weekdays, rates, share tables. app=rcna is Recovery Networks. Staff session with no pixel returns the portfolio report. recent[] only with staff or eepx_ read.

GET https://projectcommand.reversal.org/api/v1/changelog/analytics/ session|changelog_key

Query: days, organization_id, venture_id, project_id

Frequency board for cp_changelog_entries. days defaults to 7 (1-30). projects[] include share_pct and per_day. Key scope applies. UI: /changelog/.

GET https://projectcommand.reversal.org/api/v1/changelog/export/ session|changelog_key

Query: format, organization_id, venture_id, project_id, q, date_from, date_to, download

Download the scoped ship log. format=apps|csv|md|json. date_from and date_to are YYYY-MM-DD, US Eastern, inclusive. The ship log page starts the fields at the last 2 days. apps is a Markdown list grouped by project. Cap 5000 rows. json&download=0 returns the JSON envelope. UI: /changelog/#export.

GET https://projectcommand.reversal.org/api/v1/bugs/export/ session|changelog_key

Query: project_id, venture_id, organization_id, format, download

Download scoped bugs. Staff with no filter gets every row. A cpcl_ key stays inside its scope. Cap 2000. UI: project Bugs tab.

GET|POST|PATCH https://projectcommand.reversal.org/api/v1/snapins/ session|changelog_key read

Query: project_id

Body: action=enable|disable|reorder|notes, snapin_key, project_id, stack, extra_notes

Stack changelog, checks, health, mermaids, pastes, chat, pdfs, contracts, whitepapers on a project.

GET|POST https://projectcommand.reversal.org/api/v1/checks/ session|changelog_key

Query: project_id

Body: action=run|context|override|enable|disable|create|attest, project_id, check_key, base_url, env_rel_path, param_value, runner

Parameter catalog in cp_checks. Security and .env first. INSERT or POST action=create to snap in more. .env values are never returned. UI: /checks/. DataPolicy standards render under that audit.

GET|POST https://projectcommand.reversal.org/api/v1/holdings-groups/ session|cpcl_

Body: action=sync, csrf on session write

Mirrors ee_holdings.`groups` and user_groups onto cp_groups (source=holdings) under the EE Holdings project. Holdings is source of truth. UI: /groups/.

GET|POST https://projectcommand.reversal.org/api/v1/sales-groups/ session|cpcl_

Body: action=sync, csrf on session write

Mirrors salesdb.sales_groups and sales_group_members onto cp_groups (source=sales). Sales is source of truth. API only; Holdings groups use /groups/.

GET|POST https://projectcommand.reversal.org/api/v1/finance-groups/ session|cpcl_

Body: action=sync, csrf on session write

Mirrors finance_db.finance_groups onto cp_groups (source=finance) under the EE Financial project. Finance admin is source of truth. UI: https://ee.financial/admin/dashboard/#product-groups

GET|POST https://projectcommand.reversal.org/api/v1/venture-health/ session|changelog_key

Query: project_id

Body: action=save_base|add|remove|required|run, project_id, base_url, label, path, expect_status, is_required, url_id

One checklist per venture. Privacy, whitepaper, /seller, and the 404 row start required. is_required 1 counts toward Required done. Optional rows still run. Probes do not follow redirects. UI: /projects/view/?tab=health.

GET|POST https://projectcommand.reversal.org/api/v1/project-coowners/ session|changelog_key

Query: project_id, public_id

Body: action=add|remove, project_id, public_id, email, staff_id

Owner or operator, or a cpcl_ key that covers the project. A new co-owner signs in only to attached projects. Role owner is never changed. The email has a sign-in link and a view link. A new password is emailed once and is not returned. Changing the accountable owner or EE product manager on project save sends the same links to the stored inbox.

GET|POST https://projectcommand.reversal.org/api/v1/staff-roster/ session|changelog_key

Query: venture_id, project_id, action=list|check|board

Body: action=upsert|remove|seed|check, venture_id, project_id, role_key, role_label, person_name, person_email, status, is_required, id

Org roles to build out on a venture or project. Not login co-owners. Required seats must be filled for action=check to pass. UI: /staff/ and project tab Staff.

GET|POST|PATCH https://projectcommand.reversal.org/api/v1/helpdesk/ session|api_key|cpcl_

Query: project_id, project_slug, venture_id, organization_id, company_id, id, status, limit, offset

Body: project_id, project_slug, subject, body, priority, channel, requester_name, requester_email, page_url, source_ref, status, assignee_staff_id, action=reply, reply, is_internal

Ticket lifecycle per project. priority is low, medium, high, or urgent. status is open, in_progress, waiting, resolved, or closed. A cpcl_ key is locked to its company, venture, or project. Open creates write a Command alert. PATCH can set status/priority/assignee or action=reply. Distinct from /api/v1/contact/ helpdesk notes. UI: /helpdesk/.