API Reference
API
Scope
This file is the authoritative repo-owned API and callback surface inventory. It must stay in lockstep with:
fabric-manifest.json->apis.exposeddocs/INTEGRATIONS.md-> authoritative exposed-surface inventory
No OpenAPI or Swagger export exists today.
Authoritative Exposed Surface Inventory
The exact repo-owned exposed HTTP/MCP surfaces are:
GET /api/method/jhf_spindle_core.api.health.integration_statusPOST /api/method/jhf_spindle_core.api.webhooks.paddlePOST /api/method/jhf_spindle_core.api.webhooks.stripePOST /api/method/jhf_spindle_core.api.webhooks.supplier_intakePOST /api/method/jhf_spindle_core.api.webhooks.website_contact_intakePOST /api/method/jhf_spindle_core.api.workflows.request_approvalPOST /api/method/jhf_spindle_core.api.workflows.request_supplier_intake_approvalPOST /api/method/jhf_spindle_core.api.workflows.request_revenue_event_approvalPOST /api/method/jhf_spindle_core.api.workflows.dispatch_approval_packetPOST /api/method/jhf_spindle_core.api.workflows.materialize_dispatch_callback_jobPOST /api/method/jhf_spindle_core.api.workflows.post_supplier_intakePOST /api/method/jhf_spindle_core.api.workflows.post_revenue_eventPOST /api/method/jhf_spindle_core.api.weft_workspace.preview_workspace_candidate_bindingPOST /api/method/jhf_spindle_core.api.weft_workspace.read_workspace_candidate_bindingPOST /api/method/jhf_spindle_core.api.weft_workspace.materialize_workspace_candidate_bindingPOST /api/method/jhf_spindle_core.api.callbacks.openclaw_approvalPOST /api/method/jhf_spindle_core.api.callbacks.n8n_job_resultPOST /api/method/jhf_spindle_core.api.callbacks.n8n_hil_decisionPOST /api/method/jhf_spindle_core.api.support_cases.zammad_inboundPOST /api/method/jhf_spindle_core.api.support_cases.zammad_outboundPOST /api/method/jhf_spindle_core.api.support_cases.support_contextPOST /api/method/jhf_spindle_core.api.identity_projections.plane_access_factPOST /api/method/jhf_spindle_core.api.identity_projections.plane_access_fact_batchPOST /api/method/jhf_spindle_core.api.identity_projections.lifecycle_fact_batchPOST /api/method/jhf_spindle_core.api.identity_projections.keystore_bootstrap_principal_truthPOST /mcpGET /healthzGET /capability-inventory
The seven workflows.* paths plus the three weft_workspace.* paths are repo-owned HTTP surfaces, but they are internal workflow APIs rather than public third-party integration endpoints.
The canonical machine-readable contract for the seven workflows.* paths is docs/contracts/spindle-workflow-surfaces-v1.json.
materialize_dispatch_callback_job is an internal operator/test-harness workflow path for pre-creating Spindle-owned Dispatch Job truth before signed external callbacks are replayed.
preview_workspace_candidate_binding is a read-only preview lane for the first Weft candidate-binding loop and does not materialize ERP truth.
read_workspace_candidate_binding is the bounded owner-backed readback lane for the same candidate family and remains non-terminal until a later admitted materialization path exists.
materialize_workspace_candidate_binding is the first admitted bounded review-task materialization lane for the same candidate family and still keeps closeout non-terminal.
Execution Resilience Readback Boundary
The callback and dispatch surfaces below consume the canonical Fabric execution-resilience truth.
- callback receipt is execution evidence, not business closeout
- transport success or retry progress is not domain completion
- owner readback from Spindle business truth is still required before any workflow can claim terminal closeout
- when callback or retry evidence exists without owner readback, the posture remains fail-closed
Surface Contracts
integration_status
- path:
/api/method/jhf_spindle_core.api.health.integration_status - type: REST API
- methods:
GET - auth: none
- stability: stable
- source contract:
jhf_spindle_core.api.health.integration_status - request shape:
- no request body
- response shape:
- JSON/Frappe response with lightweight runtime and integration-status fields
- purpose: lightweight runtime presence and integration snapshot
paddle webhook
- path:
/api/method/jhf_spindle_core.api.webhooks.paddle - type: Webhook
- methods:
POST - auth: HMAC signature using
PADDLE_WEBHOOK_SECRET - stability: stable
- source contract:
docs/contracts/paddle-transaction-completed.json - request shape:
- provider webhook JSON payload
- raw body is signature-relevant
- response shape:
- JSON/Frappe acknowledgement or signature-validation error
- purpose: stage Paddle revenue events into append-only integration evidence
stripe webhook
- path:
/api/method/jhf_spindle_core.api.webhooks.stripe - type: Webhook
- methods:
POST - auth: HMAC signature using
STRIPE_WEBHOOK_SECRET - stability: stable
- source contract:
docs/contracts/stripe-invoice-paid.json - request shape:
- provider webhook JSON payload
- raw body is signature-relevant
- response shape:
- JSON/Frappe acknowledgement or signature-validation error
- purpose: stage Stripe revenue events into append-only integration evidence
supplier_intake webhook
- path:
/api/method/jhf_spindle_core.api.webhooks.supplier_intake - type: Webhook
- methods:
POST - auth: HMAC signature using
N8N_SHARED_SECRET - stability: stable
- source contract:
docs/contracts/n8n-supplier-intake.json - request shape:
- normalized supplier-intake JSON payload
- may include OCR-style nested vendor, invoice, totals, line_items, and attachments structures
- response shape:
- JSON/Frappe acknowledgement or signature-validation error
- purpose: create staged
Supplier Intakeevidence
website_contact_intake webhook
- path:
/api/method/jhf_spindle_core.api.webhooks.website_contact_intake - type: Webhook
- methods:
POST - auth: HMAC signature using
ERP_API_SHARED_SECRET - stability: stable
- source contract:
docs/contracts/website-contact-intake.json - request shape:
- normalized website contact-intake JSON payload with
contact,interest,profiling,site, andfabric_event - raw body is signature-relevant
- normalized website contact-intake JSON payload with
- response shape:
- JSON/Frappe acknowledgement with
integration_event,target_doctype,lead, andack
- JSON/Frappe acknowledgement with
- purpose: accept website-originated Helpifyr intake, persist the integration event, and create or update an ERP
Lead
request_approval workflow
- path:
/api/method/jhf_spindle_core.api.workflows.request_approval - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.request_approval - request shape:
- Frappe JSON body or form payload carrying the target document reference and approval context
- published field posture is normalized in
docs/contracts/spindle-workflow-surfaces-v1.json
- response shape:
- JSON/Frappe response with approval packet metadata and OpenClaw dispatch bundle when applicable
- purpose: create or reuse an approval packet for generic ERP approval-triggered work
request_supplier_intake_approval workflow
- path:
/api/method/jhf_spindle_core.api.workflows.request_supplier_intake_approval - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.request_supplier_intake_approval - request shape:
- Frappe JSON body carrying
Supplier Intakeidentity and approval context
- Frappe JSON body carrying
- response shape:
- JSON/Frappe response with approval-packet status and outbound approval bundle
- purpose: route supplier intake review into the approval matrix and packet flow
request_revenue_event_approval workflow
- path:
/api/method/jhf_spindle_core.api.workflows.request_revenue_event_approval - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.request_revenue_event_approval - request shape:
- Frappe JSON body carrying
Revenue Eventidentity and approval context
- Frappe JSON body carrying
- response shape:
- JSON/Frappe response with approval-packet status and outbound approval bundle
- purpose: route revenue-event review into the approval matrix and packet flow
dispatch_approval_packet workflow
- path:
/api/method/jhf_spindle_core.api.workflows.dispatch_approval_packet - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.dispatch_approval_packet - request shape:
- Frappe JSON body referencing the existing approval packet and dispatch options
- response shape:
- JSON/Frappe response with dispatch result metadata
- purpose: send an already-created approval packet into OpenClaw or another approved dispatch path
materialize_dispatch_callback_job workflow
- path:
/api/method/jhf_spindle_core.api.workflows.materialize_dispatch_callback_job - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
jhf_spindle_core.api.workflows.materialize_dispatch_callback_jobandjhf_spindle_core.services.document_dispatch.materialize_callback_dispatch_job - request shape:
- JSON body with required
dispatch_job - optional
dispatch_key,document_type,document_name,company,job_type,external_system,provider,status,callback_url,webhook_url, andcallback_payload
- JSON body with required
- response shape:
- JSON/Frappe response with the created or reused
Dispatch Jobsummary
- JSON/Frappe response with the created or reused
- purpose: materialize owner-approved callback-bound
Dispatch Jobtruth before a signedn8n_job_resultcallback is replayed - fail-closed posture:
- the callback endpoint still rejects unknown
dispatch_jobvalues - operators must create or reuse the
Dispatch Jobthrough this path or the equivalent bench-execute service call before replaying a jhf-wire/Storecove callback
- the callback endpoint still rejects unknown
post_supplier_intake workflow
- path:
/api/method/jhf_spindle_core.api.workflows.post_supplier_intake - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.post_supplier_intakeanddocs/INTEGRATIONS.mdsupplier-intake posting contract - request shape:
- JSON body with
name - optional
force
- JSON body with
- response shape:
- JSON/Frappe response referencing the resulting draft
Purchase Invoiceor posting error state
- JSON/Frappe response referencing the resulting draft
- purpose: turn approved staged supplier intake into a draft ERP purchase invoice
post_revenue_event workflow
- path:
/api/method/jhf_spindle_core.api.workflows.post_revenue_event - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: internal
- source contract:
jhf_spindle_core.api.workflows.post_revenue_eventanddocs/INTEGRATIONS.mdrevenue-event posting contract - request shape:
- JSON body with
name
- JSON body with
- response shape:
- JSON/Frappe response referencing the resulting draft
Sales Invoiceor posting error state
- JSON/Frappe response referencing the resulting draft
- purpose: turn staged revenue intake into a draft ERP sales invoice
preview_workspace_candidate_binding workflow
- path:
/api/method/jhf_spindle_core.api.weft_workspace.preview_workspace_candidate_binding - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller (
X-JHF-Weft-Caller+X-SignatureHMAC withWEFT_WORKSPACE_SHARED_SECRETfor guest/service-caller mode) - stability: internal
- source contract:
docs/contracts/weft-workspace-binding-reminder-truth.json - request shape:
- JSON body carrying one Weft candidate envelope with required tenant, company, source, privacy, ACL, and Fabric-admission references
- response shape:
- JSON/Frappe response with normalized candidate payload plus explicit non-terminal Spindle readback
- purpose: consume the first-loop Weft candidate in a fail-closed read-only preview lane without claiming Spindle materialization or local done truth
- fail-closed posture:
- missing or conflicting required candidate fields are rejected
- guest/service-caller traffic without the admitted Weft caller identity or valid HMAC signature is rejected
- candidate readback stays non-terminal and
closeout_allowed=false - no ERP object truth is created through this lane
read_workspace_candidate_binding workflow
- path:
/api/method/jhf_spindle_core.api.weft_workspace.read_workspace_candidate_binding - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller (
X-JHF-Weft-Caller+X-SignatureHMAC withWEFT_WORKSPACE_SHARED_SECRETfor guest/service-caller mode) - stability: internal
- source contract:
docs/WEFT_WORKSPACE_BINDING_AND_REMINDER_TRUTH.md - request shape:
- JSON body carrying the same Weft candidate envelope as the preview lane, either flat or nested under
candidate - optional
owner_readback_route_ref/readback_refto prove the caller is using the canonical Spindle-owned readback ref
- JSON body carrying the same Weft candidate envelope as the preview lane, either flat or nested under
- response shape:
- JSON/Frappe response with canonical owner-backed route ref, candidate summary, and explicit non-terminal readback posture
- purpose: return bounded Spindle-owned readback for one Weft candidate ref without claiming ERP materialization or local done truth
- fail-closed posture:
- missing or conflicting required candidate fields are rejected
- guest/service-caller traffic without the admitted Weft caller identity or valid HMAC signature is rejected
- mismatched owner-readback ref is rejected
- readback remains non-terminal with
materialization_state=needs_human_reviewandcloseout_allowed=falseuntil a later admitted materialization lane exists
materialize_workspace_candidate_binding workflow
- path:
/api/method/jhf_spindle_core.api.weft_workspace.materialize_workspace_candidate_binding - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller (
X-JHF-Weft-Caller+X-SignatureHMAC withWEFT_WORKSPACE_SHARED_SECRETfor guest/service-caller mode) - stability: internal
- source contract:
docs/WEFT_WORKSPACE_BINDING_AND_REMINDER_TRUTH.md - request shape:
- JSON body carrying the same Weft candidate envelope as the preview lane, either flat or nested under
candidate
- JSON body carrying the same Weft candidate envelope as the preview lane, either flat or nested under
- response shape:
- JSON/Frappe response with canonical owner-backed readback ref, one materialized Spindle review-task artifact, and explicit non-terminal readback posture
- purpose: create or reuse one bounded Spindle-owned review task for the first admitted
spindle_context_bindingmaterialization lane without claiming customer/case closeout or local done truth - fail-closed posture:
- missing or conflicting required candidate fields are rejected
- guest/service-caller traffic without the admitted Weft caller identity or valid HMAC signature is rejected
- repeated retries must resolve to the same bounded review artifact instead of creating duplicate business effects
- readback stays
closeout_allowed=falseeven whenmaterialization_state=materialized
openclaw_approval callback
- path:
/api/method/jhf_spindle_core.api.callbacks.openclaw_approval - type: Callback
- methods:
POST - auth: HMAC signature, optional idempotency key
- stability: stable
- source contract:
docs/contracts/openclaw-approval-callback.json - request shape:
- signed approval decision payload with packet identity, callback token, decision, and actor metadata
- response shape:
- JSON/Frappe acknowledgement or signature/idempotency error
- purpose: apply approval decisions to
Approval Packetbacked ERP flows
n8n_job_result callback
- path:
/api/method/jhf_spindle_core.api.callbacks.n8n_job_result - type: Callback
- methods:
POST - auth: HMAC signature, optional idempotency key
- stability: stable
- source contract:
docs/contracts/n8n-document-dispatch.json - request shape:
- signed job-result or dispatch-result payload with correlation/dispatch identifiers
- response shape:
- JSON/Frappe acknowledgement or signature/idempotency error
- purpose: ingest dispatch or workflow result state
- fail-closed posture:
- callback acknowledgement confirms signed receipt and correlation only
- business closeout still depends on Spindle-owned readback of the target ERP truth
- retry exhaustion without owner readback must remain explicit dead-letter or owner-followthrough truth
n8n_hil_decision callback
- path:
/api/method/jhf_spindle_core.api.callbacks.n8n_hil_decision - type: Callback
- methods:
POST - auth: HMAC signature, optional idempotency key
- stability: stable
- source contract:
docs/contracts/n8n-hil-decision.json - request shape:
- signed HiL-decision payload for an existing approval packet
- response shape:
- JSON/Frappe acknowledgement or signature/idempotency error
- purpose: apply
n8nHiL decisions toApproval Packetbacked flows
zammad_inbound support webhook
- path:
/api/method/jhf_spindle_core.api.support_cases.zammad_inbound - type: Webhook
- methods:
POST - auth: HMAC signature (
X-Signature) withZAMMAD_WEBHOOK_SECRET(fallbackN8N_SHARED_SECRET) - stability: stable
- source contract:
docs/contracts/zammad-support-inbound.json,docs/contracts/zammad-normalization-rules.json,docs/contracts/support-case-envelope.json - request shape:
- signed ticket/message event payload with ticket state, priority, sequence, and optional business refs
- Zammad ticket lifecycle variants, priority labels, status labels, attachment metadata, business-ref shortcuts, and Fabric producer event type mapping follow
docs/contracts/zammad-normalization-rules.json
- response shape:
- JSON acknowledgement with event audit key, correlation envelope, ordering result, context hydration summary, and
fabric_handoff
- JSON acknowledgement with event audit key, correlation envelope, ordering result, context hydration summary, and
- purpose: ingest support events idempotently into Spindle support evidence with Fabric-compatible envelope metadata
- fail-closed posture:
- after local idempotent persistence, canonical Fabric support handoff must succeed
- on handoff failure, endpoint returns
ok=falsewithreason=fabric_support_handoff_failedand marks the integration event failed
zammad_outbound support adapter
- path:
/api/method/jhf_spindle_core.api.support_cases.zammad_outbound - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/zammad-support-outbound.json,docs/contracts/zammad-normalization-rules.json,docs/contracts/support-case-envelope.json - request shape:
- ticket-scoped operation (
reply,note,status) plus message/status payload and optional correlation envelope
- ticket-scoped operation (
- downstream target behavior:
reply/note->POST /api/v1/ticket_articlesstatus->PUT /api/v1/tickets/{ticket_id}with state update payload
- response shape:
- JSON outcome with audit event id, delivery result, and correlation envelope
- purpose: produce and deliver bounded support updates toward Zammad while preserving idempotent audit evidence
support_context enrichment endpoint
- path:
/api/method/jhf_spindle_core.api.support_cases.support_context - type: internal workflow REST API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/support-case-envelope.json - request shape:
business_refslist with{doctype,name}rows
- response shape:
- hydrated object list plus explicit missing-object and partial-enrichment markers
- purpose: expose replay-safe business context hydration for support case enrichment
plane_access_fact identity projection
- path:
/api/method/jhf_spindle_core.api.identity_projections.plane_access_fact - type: internal identity projection API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/plane-access-fact.json - request shape:
- one of
technical_subjectorbusiness_identity_id
- one of
- response shape:
- normalized fail-closed access fact for Plane eligibility and role mapping
- includes explicit
claim_principal_type,lifecycle_state,employment_state,plane_login_allowed,plane_eligibility,project_manager_*, andspecial_posture_*semantics (contract v3)
- purpose: provide spindle-owned business identity truth for downstream Fabric/Heddle consumers
plane_access_fact_batch identity projection
- path:
/api/method/jhf_spindle_core.api.identity_projections.plane_access_fact_batch - type: internal identity projection API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/plane-access-fact.json - request shape:
- optional
limit(1..500, default100)
- optional
- response shape:
- array of normalized fail-closed access facts
- purpose: publish batch-ready access facts without direct database reads in downstream systems
lifecycle_fact_batch identity projection
- path:
/api/method/jhf_spindle_core.api.identity_projections.lifecycle_fact_batch - type: internal identity projection API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/lifecycle-access-fact.json - request shape:
- optional
limit(1..500, default100)
- optional
- response shape:
- compact lifecycle and dominance facts for policy checks
- includes claim-ready
claim_principal_typeandlifecycle_stateplus employee-onlyemployment_state
- purpose: publish lifecycle/suspension/offboarding truth in a machine-readable, fail-closed format
keystore_bootstrap_principal_truth identity projection
- path:
/api/method/jhf_spindle_core.api.identity_projections.keystore_bootstrap_principal_truth - type: internal identity projection API
- methods:
POST - auth: ERP session auth or trusted internal caller
- stability: stable
- source contract:
docs/contracts/keystore-primary-admin-principal.json - request shape:
- optional
technical_subject; defaults to configuredheddle_superuser_subject
- optional
- response shape:
- machine-readable bootstrap principal truth payload with contract/projection references
- purpose: expose deterministic live bootstrap principal truth for keystore/deployment consumers without local fixture fallback
MCP gateway
- path:
/mcp - type: MCP
- methods:
POST - transport: JSON-RPC
- auth:
X-JHF-Spindle-Keyfor productive requests; only narrow handshake methods are auth-exempt - stability: stable
- source contract:
docs/MCP.md,docs/MCP_OPERATIONS.md - request shape:
- JSON-RPC MCP request payload
- response shape:
- JSON-RPC MCP response payload
- purpose: tool, prompt, and resource access for operators and agents
MCP healthz
- path:
/healthz - type: REST API
- methods:
GET - auth: none
- stability: stable
- source contract: MCP gateway server runtime
- request shape:
- no request body
- response shape:
- liveness response from the MCP gateway
- purpose: MCP gateway liveness
MCP capability inventory
- path:
/capability-inventory - type: REST API
- methods:
GET - auth: none
- stability: stable
- source contract:
apps/jhf_spindle_core/jhf_spindle_core/mcp/contracts/capability_inventory_v1.json(spindle-capability-inventory-v1) - request shape:
- no request body
- response shape:
- versioned owner/service metadata, runtime and interface posture, classification, freshness, and declared interface metadata
- purpose: Fabric/Lantern readback of the admitted read-only Spindle interface inventory; no ERP objects, secrets, tool catalog, or write authority are returned
Stability Rules
stablemeans the surface is already relied upon by repo-owned workflows or external counterpartiesinternalmeans the surface is HTTP-exposed but intended for ERP session use, trusted internal callers, or tightly coupled workflow partners- write and control operations remain governed by the repo-owned product rules, not by arbitrary external callers or future Fabric automation
Known Gaps
- no OpenAPI or Swagger export
- no dedicated
/versionor/metricsendpoint yet;/capability-inventoryis intentionally limited to MCP interface metadata
License notice: AGPLv3 (GNU Affero General Public License v3.0) Website: https://helpifyr.com