mngr
API version 2026-06-15base url https://api.mngr.dev

API reference

The mngr API is organized around REST. Requests are authenticated per org, bodies are JSON, and every mutating endpoint is idempotent. Decisions issued through the API are production decisions: they are logged, traced, and binding within your org's configured governance window.

Authentication

Authenticate with your secret key using HTTP basic auth (key as username, empty password). Test-mode keys (sk_test_) issue decisions against a fixture org. Live keys (sk_live_) issue decisions against yours.

curl https://api.mngr.dev/v1/decisions \
  -u sk_test_51NqRk2GLb0sMn8:

Keys are org-scoped. Rotating a key does not reverse decisions issued under it.

The decision object

id stringUnique identifier, prefixed dec_.
decision enumOne of approve, approve_with_concerns, defer, delegate, escalate.
rationale stringA single sentence of managerial context.
confidence number0–1. Calibrated weekly against realized outcomes.
reversible booleanWhether the decision can be reversed in-window.
reversal_window_days integerDefaults to 90. Reversals consume the original DU cost plus one.

POST /v1/decisions

Creates a decision. p50 latency 141 ms.

context string, requiredThe situation requiring a determination. Plain prose.
requested_by stringThe user on whose behalf the decision is requested.
urgency enumnormal or high. High-urgency decisions consume 3× DU.
stakeholders arrayOptional. Decisions with more than 6 stakeholders are escalated automatically.
curl https://api.mngr.dev/v1/decisions \
  -u sk_live_51NqRk2GLb0sMn8: \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: q3-headcount-0042" \
  -d '{
    "context": "Two teams have claimed the same Q3 headcount.",
    "requested_by": "usr_8x2k1"
  }'
import Mngr from "mngr";
const mngr = new Mngr(process.env.MNGR_SECRET_KEY);

const decision = await mngr.decisions.create({
  context: "Two teams have claimed the same Q3 headcount.",
  requested_by: "usr_8x2k1",
});

decision.decision; // "defer"
decision.confidence; // 0.61
import os

import mngr

client = mngr.Client(api_key=os.environ["MNGR_SECRET_KEY"])

decision = client.decisions.create(
    context="Two teams have claimed the same Q3 headcount.",
)

assert decision.reversible  # 90-day window by default

Response

{
  "id": "dec_8Fk32a",
  "object": "decision",
  "created": 1770412800,
  "decision": "defer",
  "rationale": "Additional context is expected to emerge.",
  "revisit_at": "2026-10-01T09:00:00Z",
  "confidence": 0.61,
  "reversible": true,
  "reversal_window_days": 90
}

POST /v1/approvals

Submits a request for approval. Chains are resolved server-side from the org graph, in order, with per-hop timeouts. A chain may visit the same approver more than once; this is expected in matrixed organizations.

type enum, requiredOne of expense, purchase, access, exception.
amount_usd numberRequired for monetary types.
requester string, requiredThe user requesting approval.
memo stringFree-text context, visible to every hop in the chain.

Response — 202 Accepted

{
  "id": "apr_0kq3k1",
  "object": "approval",
  "status": "pending",
  "amount_usd": 41.50,
  "approver_chain": ["mgr_2231", "mgr_0417", "mgr_2231"],
  "position_in_queue": 4
}

POST /v1/one-on-ones

Creates a recurring one-on-one between a manager instance and a report. Either party may reschedule a session. reschedule_count is preserved across reschedules and cannot be reset.

report string, requiredThe user the one-on-one is for.
manager stringDefaults to the report's assigned manager instance.
recurrence enumOne of weekly, biweekly, monthly. Defaults to weekly.

Response — 201 Created

{
  "id": "ooo_2m81xk",
  "object": "one_on_one",
  "status": "scheduled",
  "scheduled_for": "2026-08-12T14:30:00Z",
  "duration_minutes": 30,
  "agenda": ["Career growth", "Q3 priorities", "Open items"],
  "reschedule_count": 3
}

GET /v1/priorities

Returns the org's current priority stack, ordered. This endpoint takes no parameters. All levels are P0 by default; additional levels are available on Enterprise.

Response — 200 OK

{
  "object": "list",
  "url": "/v1/priorities",
  "data": [
    { "id": "pri_g81m2", "name": "Migration to v2 decision schema", "level": "P0" },
    { "id": "pri_g81m3", "name": "Q3 hiring plan", "level": "P0" }
  ],
  "has_more": true
}

POST /v1/feedback

Composes performance feedback in the org's configured format. The default format is sandwich. The delivered field remains false until the feedback is delivered, which is outside the scope of the API.

subject string, requiredThe user the feedback concerns.
channel enumOne of written, verbal. verbal is not yet implemented.
topic stringNarrows the feedback to one area of performance.

Response — 200 OK

{
  "id": "fdb_9k2m1x",
  "object": "feedback",
  "format": "sandwich",
  "segments": [
    { "tone": "positive", "text": "Your throughput this quarter has been strong." },
    { "tone": "developmental", "text": "Review turnaround is trending 40% above team median." },
    { "tone": "positive", "text": "Your throughput this quarter has been strong." }
  ],
  "delivered": false
}

Idempotency

Send an Idempotency-Key header with any POST. Replaying a request returns the original decision with idempotency-status: replayed. Asking the same question again does not change the answer.

Rate limits

60 decisions per minute per org by default. Sustained load above the limit degrades confidence scores before it degrades availability. Decision outcomes shift measurably across an unbroken session (Danziger et al., PNAS 2011). The limiter exists to protect calibration. 429 responses set Retry-After.

Errors

mngr uses conventional HTTP status codes. Machine-readable codes appear in error.code.

400 invalid_request_errorThe body is malformed or a required parameter is missing.
401 authentication_errorThe API key is missing, invalid, or revoked.
402 quota_exceededThe org's decision-unit balance is exhausted for the period.
404 resource_missingNo resource exists with that id.
409 MANAGER_CONFLICTEDThe assigned manager instance holds both positions on this decision. Retry after the conflict window closes.
422 decision_not_actionableThe context was insufficient to form a determination.
429 rate_limitedToo many decisions. See Retry-After.
500 internal_errorSomething failed on our side. The decision will be reissued.

Webhooks

Register an HTTPS endpoint to receive events. Payloads are signed with an HMAC in the mngr-signature header. Events: decision.created, decision.reversed, approval.resolved, oneonone.rescheduled, reorg.

mngr.webhooks.on("reorg", async () => {
  // The reorg event has no payload.
  await refetchAllResources();
});

The reorg event has no payload schema. Consumers are advised to re-fetch all resources.

Changelog

2026-06-15Current version. Confidence scores now round half away from zero.
2026-05-20Rate-limit headers renamed to the IETF draft standard names.
2026-03-02Added the delegate decision type. A decision may now resolve to the decision being made elsewhere.
2025-11-01DELETE /v1/morale now returns 410 Gone.