Developer Hub › Agent Cookbook
ProjexCloud · Build

Agent Cookbook

Seven agent types you can build on ProjexCloud, each with the exact SDKs, capability scopes, and runnable sample code. Every agent expresses a goal as an Intent, plans against the CapabilityGraph (your SDKs + connectors + MCP tools), and executes each step gated by a capability token, metered, audited, and traceable — so nothing runs off the rails.

The agent model in one screen

Create an agent identity with a scoped, time-boxed capability set; give it an intent; let it plan and execute. Under the hood, each step mints a single-use capability token, passes the meter gate, and lands in the audit + trace log.

import { resolveIdentityContext } from '@projexlight/sdk-identity-resolver/client';
import { AgentRuntime } from '@projexlight/sdk-agent-runtime/client';

const ctx = await resolveIdentityContext(token);            // six-layer identity
const agent = AgentRuntime.create({
  agent_id: 'my-agent',
  acting_for: ctx.primary_persona_id,
  scope: ['crm.read', 'notification.send'],                 // least privilege
  ttl_seconds: 300,                                         // hard deadline
});

const plan   = await agent.plan({ goal, subject, parameters });  // typed multi-step plan
const result = await agent.execute(plan);                        // token+meter+audit+trace per step
console.log(result.trace_id);                                    // open in sdk-trace

Every REST endpoint below is a step the agent's plan can execute — or that you can call directly. All require Authorization: Bearer <tenant-jwt> unless noted. Full payloads/enums are in the API Reference.

1

Sales Cadence Agent

Runs a multi-touch outreach cadence — enroll a lead, send each step in its send-window, and stop automatically on reply, opt-out, or a bounce.

sdk-sequencesdk-notificationsdk-deliverability

Sample

const agent = AgentRuntime.create({
  agent_id: 'sales-cadence-agent', acting_for: ctx.primary_persona_id,
  scope: ['sequences.enroll','sequences.control','notification.send','deliverability.check'],
  ttl_seconds: 300,
});

// 1 · Pre-send safety: is this address suppressed / the channel paused?
POST /api/deliverability/check
     { "tenant_id": TID, "channel": "email", "address": "lead@acme.com" }
//   → { data: { suppressed: false } }   (skip if true)

// 2 · Enroll the lead into a cadence (idempotent)
POST /api/sequences/enrollments
     { "tenant_id": TID, "sequence_id": SEQ, "subject_persona_id": LEAD,
       "send_window": { "quiet_hours": [21,7], "weekdays": [1,2,3,4,5] } }

// 3 · The executor drains due steps (send-window gated, dedup-safe)
POST /api/sequences/tick        // a scheduler/agent tick; sends via sdk-notification

// 4 · Reactive control — pause the enrollment the moment the lead replies
POST /api/sequences/enrollments/:enrollment_id/control
     { "action": "pause", "control_reason": "reply_received" }
Guardrails: the frequency-cap + circuit-breaker guard blocks over-sending; deliverability suppression + reputation auto-pause protect your domain; every send is metered and audited. The agent's scope can't send outside these SDKs.
2

Booking & No-Show Agent

Offers real availability, books a slot (double-book safe), sends reminders, and rescues no-shows by re-booking — all in the host's timezone.

sdk-scheduling

Sample

const agent = AgentRuntime.create({
  agent_id: 'booking-agent', acting_for: ctx.primary_persona_id,
  scope: ['scheduling.read','scheduling.book','scheduling.reschedule'],
  ttl_seconds: 180,
});

// 1 · Open slots for a date (business hours + buffers, IANA tz, existing appts excluded)
GET  /api/scheduling/availability?tenant_id=TID&host_persona_id=HOST&date=2026-02-14

// 2 · Book (transactional double-book prevention → 409 if the slot was just taken)
POST /api/scheduling/appointments
     { "tenant_id": TID, "host_persona_id": HOST, "meeting_type_id": MT,
       "start_time": "2026-02-14T15:00:00Z", "end_time": "2026-02-14T15:30:00Z",
       "subject_persona_id": LEAD }

// 3 · Public, no-login booking link (anonymous prospect books + confirms by token)
GET  /api/scheduling/public/links/:slug/availability?date=2026-02-14
POST /api/scheduling/public/links/:slug/book         // → { public_token }
POST /api/scheduling/public/appointments/:public_token/confirm

// 4 · No-show rescue (worker scans past-grace, un-attended appts → rebook)
POST /api/scheduling/no-show-scan   { "grace_minutes": 10 }
Guardrails: public booking authorizes on a capability token, never the appointment id (no IDOR); booking windows (max-days-ahead, min-notice) are enforced server-side; reminders/no-show run as opt-in workers.
3

Voice Outreach Agent

Places a recorded call from a tracked number, detects a human vs voicemail (AMD), and logs the outcome to the CRM timeline — with recording gated on consent.

connector-twilio-voicesdk-consentsdk-crm

Sample

const agent = AgentRuntime.create({
  agent_id: 'voice-outreach-agent', acting_for: ctx.primary_persona_id,
  scope: ['voice.provision','voice.call','consent.check','crm.activity.log'],
  ttl_seconds: 300,
});

// 1 · A tracking number pinned to this campaign (one active claim per tenant+number)
POST /api/voice/tracking-numbers   { "tenant_id": TID, "install_id": INST, "purpose": "q1-outreach" }

// 2 · Place the call. Recording is CONSENT-GATED: if no affirmative consent on file,
//     recording is withheld at source (Twilio is never asked to record).
POST /api/voice/calls
     { "tenant_id": TID, "install_id": INST, "to_number": "+14155550123",
       "subject_persona_id": LEAD, "record": true, "machine_detection": true,
       "metadata": { "encounter_id": ENC } }     // encounter anchors the CRM bridge

// 3 · Twilio posts progress + AMD to the PUBLIC signed webhook (no JWT; X-Twilio-Signature)
POST /api/voice/webhooks/twilio/status   // AnsweredBy=machine_* → is_voicemail, and…
//   …the platform bridges the finished call into the CRM timeline automatically:
//   crm.call.logged.v1 / crm.call.missed.v1 / crm.voicemail.received.v1
Guardrails: recording fails closed — no consent decision ⇒ no recording pointer stored; webhook signatures are verified; a missed/voicemail outcome is logged distinctly so follow-up reporting never double-counts.
4

Lead Intelligence Agent

Scores an inbound lead, computes the next-best-action, and writes it as the deal's enforced NEXT action so nothing stalls.

sdk-lead-scoringsdk-crm

Sample

const agent = AgentRuntime.create({
  agent_id: 'lead-intel-agent', acting_for: ctx.primary_persona_id,
  scope: ['lead-scoring.score','crm.read','crm.next-action.write'],
  ttl_seconds: 120,
});

// 1 · Score the lead against the active model for the tenant's vertical
POST /api/lead-scoring/score
     { "tenant_id": TID, "vertical": "solar", "features": { "budget": 25000, "urgency": "high" } }
//   → { data: { score: 0.82, band: "hot" } }

// 2 · Next-best-action from the model
POST /api/lead-scoring/next-best-action   { "tenant_id": TID, "vertical": "solar", "lead_id": LEAD }

// 3 · Persist it as the deal's enforced NEXT action (save-gate: a deal can't go stale)
POST /api/crm/deals/:deal_id/next-action
     { "tenant_id": TID, "action": "book_site_survey", "due_at": "2026-02-16T00:00:00Z" }
Guardrails: the save-gate refuses to leave an open deal without a NEXT action; scoring requires an active model for the vertical (explicit 400 otherwise, never a silent guess).
5

Sales → Delivery Handoff Agent

Orchestrates a won deal into delivery as a durable saga, then gates the CS accept/reject decision through approvals.

sdk-handoffsdk-workflowsdk-approval

Sample

const agent = AgentRuntime.create({
  agent_id: 'handoff-agent', acting_for: ctx.primary_persona_id,
  scope: ['handoff.create','handoff.saga','handoff.approval'],
  ttl_seconds: 300,
});

// 1 · Create the handoff (draft), with prework / promises / milestones
POST /api/handoffs
     { "tenant_id": TID, "from_persona_id": AE, "deal_id": DEAL,
       "promises": ["go-live in 30 days"], "risks": ["data migration scope unknown"] }

// 2 · Drive kickoff/prework/milestones as an sdk-workflow saga (durable + compensating)
POST /api/handoffs/:handoff_id/saga/start      // steps recorded; rollback on failure

// 3 · File the CS accept/reject approval (subject = the handoff) and submit for review
POST /api/handoffs/:handoff_id/approval/request   { "tenant_id": TID }   // draft → pending

// 4 · Record the CS decision → reflected onto the handoff lifecycle + event
POST /api/handoffs/:handoff_id/approval/decision
     { "tenant_id": TID, "decision": "approved" }   // pending → accepted (or rejected)
Guardrails: transitions are validated against the lifecycle state machine (invalid → 409); the accept/reject decision is delegated to sdk-approval (not a bespoke gate); the saga compensates on step failure.
6

Incident Triage Agent

Opens an incident, appends an append-only evidence timeline notarised into the audit chain, and watches SLA breaches.

sdk-incidentsdk-audit

Sample

const agent = AgentRuntime.create({
  agent_id: 'incident-triage-agent', acting_for: ctx.primary_persona_id,
  scope: ['incident.create','incident.evidence','incident.transition'],
  ttl_seconds: 240,
});

// 1 · Open an incident with an SLA deadline
POST /api/incidents
     { "tenant_id": TID, "incident_type": "data_quality", "title": "Duplicate leads ingested",
       "severity": "high", "sla_due_at": "2026-02-14T20:00:00Z" }

// 2 · Append evidence (detected / root_cause / recovery / verification).
//     Append-only: each entry is hash-chained into sdk-audit; UPDATE/DELETE are blocked.
POST /api/incidents/:incident_id/evidence
     { "tenant_id": TID, "kind": "detected", "body": "Dedup monitor flagged 412 dup leads",
       "evidence_ref": "s3://ops-logs/dedup.json" }
//   → { evidence: { audit_entry_id, audit_seq, audit_entry_hash } }   // the immutability receipt

// 3 · Move the lifecycle; scan for SLA breaches (partial-index powered)
POST /api/incidents/:incident_id/transition   { "tenant_id": TID, "status": "investigating" }
GET  /api/incidents/sla-breaches?tenant_id=TID
Guardrails: evidence is tamper-evident (a DB trigger blocks edits/deletes; the FK is RESTRICT so an incident with evidence can't be erased); the audit receipt proves the text wasn't altered after recording.
7

Offer / Quote Agent

Publishes a versioned offer through an approval gate, then resolves the current live version so quotes never reference a stale price.

sdk-offer-catalogsdk-approval

Sample

const agent = AgentRuntime.create({
  agent_id: 'offer-agent', acting_for: ctx.primary_persona_id,
  scope: ['offer.author','offer.publish','offer.resolve'],
  ttl_seconds: 180,
});

// 1 · Create an offer + a draft version
POST /api/offers                       { "tenant_id": TID, "name": "Pro Plan", "slug": "pro" }
POST /api/offers/:offer_id/versions    { "tenant_id": TID, "version": "2026.1" }

// 2 · Request the publish approval (subject = the offer version) → sdk-approval
POST /api/offers/:offer_id/versions/:version_id/publish-approval   { "tenant_id": TID }

// 3 · Activate (gated: blocked while pending/rejected) → promotes to the single live version
POST /api/offers/:offer_id/versions/:version_id/activate   { "tenant_id": TID }

// 4 · Resolve the current version (live → beta → draft fallback) for a quote
GET  /api/offers/:offer_id/current?tenant_id=TID
//   Stale-reference guard: a quote pinned to a non-current version is flagged.
Guardrails: activation is blocked until the publish approval clears (409 otherwise); exactly one live version per offer; version-stamp + stale-reference guard stop quotes from citing an outdated offer.
Compose them. Real workflows chain these — a Lead Intelligence Agent scores a lead, a Sales Cadence Agent runs outreach, a Voice Outreach Agent calls, a Booking Agent schedules the demo, an Offer Agent sends the quote, and a Handoff Agent moves the won deal to delivery. Each step is a capability-token-gated, metered, audited call — one trace_id spans the whole journey.

← Developer Hub API Reference ↗ Agentic Integration ↗

ProjexCloud · Developer Hub · v3.1 · Endpoints reflect the shipped SDKs; see the API Reference for full payloads, enums, and error responses.