Skip to main content

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.exposed
  • docs/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_status
  • POST /api/method/jhf_spindle_core.api.webhooks.paddle
  • POST /api/method/jhf_spindle_core.api.webhooks.stripe
  • POST /api/method/jhf_spindle_core.api.webhooks.supplier_intake
  • POST /api/method/jhf_spindle_core.api.webhooks.website_contact_intake
  • POST /api/method/jhf_spindle_core.api.workflows.request_approval
  • POST /api/method/jhf_spindle_core.api.workflows.request_supplier_intake_approval
  • POST /api/method/jhf_spindle_core.api.workflows.request_revenue_event_approval
  • POST /api/method/jhf_spindle_core.api.workflows.dispatch_approval_packet
  • POST /api/method/jhf_spindle_core.api.workflows.materialize_dispatch_callback_job
  • POST /api/method/jhf_spindle_core.api.workflows.post_supplier_intake
  • POST /api/method/jhf_spindle_core.api.workflows.post_revenue_event
  • POST /api/method/jhf_spindle_core.api.weft_workspace.preview_workspace_candidate_binding
  • POST /api/method/jhf_spindle_core.api.weft_workspace.read_workspace_candidate_binding
  • POST /api/method/jhf_spindle_core.api.weft_workspace.materialize_workspace_candidate_binding
  • POST /api/method/jhf_spindle_core.api.callbacks.openclaw_approval
  • POST /api/method/jhf_spindle_core.api.callbacks.n8n_job_result
  • POST /api/method/jhf_spindle_core.api.callbacks.n8n_hil_decision
  • POST /api/method/jhf_spindle_core.api.support_cases.zammad_inbound
  • POST /api/method/jhf_spindle_core.api.support_cases.zammad_outbound
  • POST /api/method/jhf_spindle_core.api.support_cases.support_context
  • POST /api/method/jhf_spindle_core.api.identity_projections.plane_access_fact
  • POST /api/method/jhf_spindle_core.api.identity_projections.plane_access_fact_batch
  • POST /api/method/jhf_spindle_core.api.identity_projections.lifecycle_fact_batch
  • POST /api/method/jhf_spindle_core.api.identity_projections.keystore_bootstrap_principal_truth
  • POST /mcp
  • GET /healthz
  • GET /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 Intake evidence

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, and fabric_event
    • raw body is signature-relevant
  • response shape:
    • JSON/Frappe acknowledgement with integration_event, target_doctype, lead, and ack
  • 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 Intake identity and approval context
  • 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 Event identity and approval context
  • 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_job and jhf_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, and callback_payload
  • response shape:
    • JSON/Frappe response with the created or reused Dispatch Job summary
  • purpose: materialize owner-approved callback-bound Dispatch Job truth before a signed n8n_job_result callback is replayed
  • fail-closed posture:
    • the callback endpoint still rejects unknown dispatch_job values
    • operators must create or reuse the Dispatch Job through this path or the equivalent bench-execute service call before replaying a jhf-wire/Storecove callback

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_intake and docs/INTEGRATIONS.md supplier-intake posting contract
  • request shape:
    • JSON body with name
    • optional force
  • response shape:
    • JSON/Frappe response referencing the resulting draft Purchase Invoice or posting error state
  • 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_event and docs/INTEGRATIONS.md revenue-event posting contract
  • request shape:
    • JSON body with name
  • response shape:
    • JSON/Frappe response referencing the resulting draft Sales Invoice or posting error state
  • 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-Signature HMAC with WEFT_WORKSPACE_SHARED_SECRET for 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-Signature HMAC with WEFT_WORKSPACE_SHARED_SECRET for 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_ref to prove the caller is using the canonical Spindle-owned readback ref
  • 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_review and closeout_allowed=false until 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-Signature HMAC with WEFT_WORKSPACE_SHARED_SECRET for 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
  • 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_binding materialization 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=false even when materialization_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 Packet backed 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 n8n HiL decisions to Approval Packet backed 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) with ZAMMAD_WEBHOOK_SECRET (fallback N8N_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
  • 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=false with reason=fabric_support_handoff_failed and 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
  • downstream target behavior:
    • reply/note -> POST /api/v1/ticket_articles
    • status -> 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_refs list 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_subject or business_identity_id
  • 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_*, and special_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, default 100)
  • 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, default 100)
  • response shape:
    • compact lifecycle and dominance facts for policy checks
    • includes claim-ready claim_principal_type and lifecycle_state plus employee-only employment_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 configured heddle_superuser_subject
  • 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-Key for 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

  • stable means the surface is already relied upon by repo-owned workflows or external counterparties
  • internal means 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 /version or /metrics endpoint yet; /capability-inventory is intentionally limited to MCP interface metadata

License notice: AGPLv3 (GNU Affero General Public License v3.0) Website: https://helpifyr.com