Skip to content

Sirloin API

The contract surface of sirloin. For service overview see Sirloin. For generated proto reference see proto-api.

Surface Map

Sirloin exposes four gRPC services and a small set of HTTP endpoints (health, webhooks, MCP). The single Go process listens on three ports:

PortPurposeSource
50051gRPC + gRPC-Web (h2c)apps/sirloin/cmd/app/main.go (grpcHTTPServer)
8087Webhook intake (HTTP)apps/sirloin/cmd/app/main.go (webhookHTTPServer)
8086MCP / Foxy360 (HTTP)apps/sirloin/cmd/app/main.go (mcpHTTPServer)

Defaults: container ports per docker-compose.yml (sirloin service). Default SIRLOIN_PORT=:50051 per apps/sirloin/internal/app/config/config.go.

gRPC Services

Proto contracts live under proto/sirloin/v5/. Generated stubs are checked into apps/sirloin/internal/pkg/pb/. RPC list below is summarised; for full request/response shapes refer to the proto files and the generated docs at proto-api.

SirloinService (proto/sirloin/v5/sirloin.proto)

End-user surface: characters, media, profile, KYC. Consumed by brisket over gRPC-Web. Selected RPCs (28 total):

  • CreateCharacter, UpdateCharacter, ListCharacters, DeleteCharacter
  • GetCharacterReferenceImageUploadURL, GetCharacterReferenceDatasetUploadURLs
  • VerifyCharacterReferenceDatasetImage, DeleteCharacterReferenceDatasetImage
  • UpdateCharacterReferenceDataset, TriggerCharacterReferenceImageUploaded
  • GenerateMedia, ListMedia, ToggleMediaFavorite, ToggleMediaArchived, SetMediaDownloaded, ListMediaTags, ListMediaExamples
  • GetUserProfile, UpdateUserProfile, RequestWelcomePics, SubmitFeedback
  • GetInstagramProfile, StartKYCVerification

BillingService (proto/sirloin/v5/billing.proto)

Billing surface: subscriptions, payments, products, coupons. Consumed by brisket and strip. Selected RPCs:

  • GetCurrentUsage, ListProducts, GetWorkflowPricing
  • CreatePrimerCheckout, SubmitPaidInvoice, GetPayment, GetTransactions
  • GetSubscriptionDetails, CancelSubscription, ReactivateSubscription, CancelScheduledDowngrade, ProvideCancellationBenefit
  • RetryDunningPayment, ValidateCoupon, SetReferralCode
  • GetPaymentMethods, AddPaymentMethod, DeletePaymentMethod, SetPrimaryPaymentMethod, CreateVaultingSession
  • UpdateBillingAddress, UpdateNextBillingDateForTesting (test-only)

Behaviour notes (deferred activation, polling, invariants) are described in apps/sirloin/internal/app/services/billing/BILLING.md and the billing runbook.

StripService (proto/sirloin/v5/strip.proto)

Admin surface consumed exclusively by strip (SSR admin). Auth via short-lived admin Clerk token (see auth-model). Selected RPCs:

  • StripListUsers, StripUpdateUser
  • StripListCharacters, StripCreateCharacter, StripUpdateCharacter, StripDeleteCharacter, StripBypassCharacterOnboardingChecks
  • StripListMedia, StripFailMedia, StripListDatasetImages
  • StripListPopularExamples, StripListPopularCategories
  • StripLogAudit, StripListAuditLogs, StripGetAuditLog

FlankStorageService (proto/sirloin/v5/flank.proto) — legacy / being retired

Under T-Bone the workflow engine and storage moved into brain, which now owns workflows, subworkflows, adapters, secrets, and executions over an HTTP API. Flank is now only the visual workflow editor and reads/writes brain directly. This sirloin-hosted persistence surface is superseded. TODO(@law): remove the FlankStorageService (and the FlankMCP route below) once no flow depends on it.

Legacy persistence surface for flank workflows, adapters, secrets, executions. Authenticated by SIRLOIN_FLANK_SERVICE_TOKEN. Source: apps/sirloin/internal/app/services/flank/. RPC families:

  • Workflows: FlankCreateWorkflow, FlankUpdateWorkflow, FlankGetWorkflow, FlankListWorkflows, FlankDeleteWorkflow, FlankPublishWorkflow
  • Adapters: FlankCreateAdapterFlankDeleteAdapter
  • Secrets: FlankCreateSecretFlankResolveSecrets
  • Executions: FlankCreateExecution, FlankUpdateExecution, FlankGetExecution, FlankListExecutions

gRPC Health

grpc.health.v1.Health implemented in apps/sirloin/internal/app/services/health.go. Used by the container healthcheck (/bin/grpc_health_probe -addr=:50051).

REST Endpoints

Sirloin’s HTTP surface is intentionally narrow. Routes registered in apps/sirloin/cmd/app/main.go against webhookMux, grpcHTTPMux, and mcpMux.

MethodPathServerAuthSource
GET/healthgRPC HTTP (50051)noneinternal/app/services/health.go
POST/webhooks/chargebee/eventswebhooks (8087)HTTP Basic (SIRLOIN_CHARGEBEE_WEBHOOK_USERNAME / _PASSWORD)internal/app/services/billing/webhooks/chargebeewebhook.go
POST/webhooks/primer/disputeswebhooks (8087)HMAC over SIRLOIN_PRIMER_WEBHOOK_SECRETinternal/app/services/billing/disputes/primerwebhook.go
POST/webhooks/primer/paymentswebhooks (8087)HMAC over SIRLOIN_PRIMER_WEBHOOK_SECRETinternal/app/services/billing/webhooks/ (NewPrimerPaymentsWebhookHandler)
POST/webhooks/ondato/verification-statuswebhooks (8087)shared secret SIRLOIN_ONDATO_WEBHOOK_SECRETinternal/app/services/characters/ondato_webhook.go
ANY${SIRLOIN_FOXY360_BASE_PATH}/*MCP (8086)Clerk (SIRLOIN_FOXY360_CLERK_API_KEY) via OAuth proxyinternal/app/foxy360/, internal/app/mcpoauth/
ANY${FlankMCPBasePath}/*MCP (8086)flank service tokeninternal/app/flankmcp/legacy / being retired (workflow tooling moved to brain)

grpcHTTPMux falls back to a 404 for everything except /health and the gRPC + gRPC-Web protocol routes (apps/sirloin/cmd/app/main.go).

Webhooks Received

Chargebee Events

  • Path: POST /webhooks/chargebee/events on port 8087
  • Auth: HTTP Basic with SIRLOIN_CHARGEBEE_WEBHOOK_USERNAME / SIRLOIN_CHARGEBEE_WEBHOOK_PASSWORD. Missing creds → all webhooks rejected (config.go warns at startup).
  • Payload: Chargebee event JSON (event_type, content).
  • Behaviour: webhook is a fallback; sirloin’s own poller (every 15s, see internal/app/services/billing/events/poller.go) is the authoritative ingest path.

Primer Disputes

  • Path: POST /webhooks/primer/disputes on port 8087
  • Auth: HMAC verified with SIRLOIN_PRIMER_WEBHOOK_SECRET. 3-minute clock skew window (primer.WebhookSignedAtWithinSkew).
  • Body limit: 1 MiB (maxPrimerWebhookBodyBytes).

Primer Payments

  • Path: POST /webhooks/primer/payments on port 8087
  • Auth: same HMAC scheme as disputes.
  • Behaviour: feeds the unified payment processor (internal/app/services/billing/payments/processor.go).

Ondato KYC

  • Path: POST /webhooks/ondato/verification-status on port 8087
  • Auth: shared secret SIRLOIN_ONDATO_WEBHOOK_SECRET.

Examples

Terminal window
# health probe
curl -fsS http://localhost:50051/health
# gRPC reflection (dev only — sirloin docker-compose ships grpcui on :8821 too)
grpcurl -plaintext localhost:50051 list
grpcurl -plaintext localhost:50051 sirloin.v5.BillingService/ListProducts

Versioning

Proto package is pinned at sirloin.v5. Backwards-incompatible changes require a new package version; field deprecation follows documentation standard and auth-model for auth changes. TODO(@zen): no formal deprecation policy doc exists yet — confirm or add ADR.

TODO(@zen)

  • TODO(@zen): is there a documented sirloin.v5 deprecation policy beyond proto file conventions?
  • Foxy360 MCP routes are internal-only. The ${SIRLOIN_FOXY360_BASE_PATH}/* surface is gated by Clerk verification (SIRLOIN_FOXY360_CLERK_API_KEY) through an OAuth proxy and exposes admin/analytics tooling. Source: apps/sirloin/internal/app/foxy360/server.go:1 and registration in apps/sirloin/cmd/app/main.go (mcpHTTPServer).
  • Primer payments webhook uses the same 1 MiB body cap as disputes. maxPrimerPaymentBodyBytes = 1 * 1024 * 1024 in apps/sirloin/internal/app/services/billing/webhooks/primerpaymentwebhook.go:22, matching maxPrimerWebhookBodyBytes in apps/sirloin/internal/app/services/billing/disputes/primerwebhook.go:26.