Protocol Documentation
Table of Contents
Top
brain/v1/character_runtime.proto
AcquireCharacterExecutionRequest
AcquireCharacterExecutionResponse
CharacterAssetSourceRef
CharacterAssetSourceRef names an asset already bound to the character, by the
slot it occupies. Lineage is declared against slots rather than asset ids
because the workflow never sees an id — Sirloin mints those at commit.
| Field | Type | Label | Description |
|---|
| scope | string | | Closed policy enum as a string: upload |
| role | string | | Slot name inside scope. |
| ordinal | int32 | | |
CharacterCompletion
CharacterExecutionAsset
CharacterExecutionAsset is the only provider-to-storage creation-asset
envelope. Sirloin verifies every field before atomically binding a result.
Scope+role replace the retired flat role_key (ADR 2026-08-11).
| Field | Type | Label | Description |
|---|
| asset_kind | string | | |
| ordinal | int32 | | |
| object_key | string | | |
| content_type | string | | |
| byte_size | int64 | | |
| content_digest | bytes | | |
| provenance_json | bytes | | |
| content | bytes | | POC/reference adapters may hand small deterministic objects to Sirloin. Provider adapters should upload content-addressed objects and omit this. |
| scope | string | | Closed policy enum as a string: upload |
| role | string | | Slot name inside scope; recipe-declared, ^[a-z][a-z0-9_-]{0,63}$. |
| derived_from | CharacterAssetSourceRef | repeated | Assets this one was derived from, as slots on the same character. Sirloin resolves each to an asset id at commit and records an edge; a source that does not resolve fails the commit. Scope policy decides whether declaring any is mandatory (ADR 2026-08-11). |
CharacterExecutionCheckpoint
| Field | Type | Label | Description |
|---|
| checkpoint_json | bytes | | |
CharacterExecutionEffectResult
CharacterExecutionEffectStart
CharacterExecutionResponse
CharacterExecutionTerminalResult
CharacterRecipeValidationIssue
CheckCharacterRuntimeHealthRequest
CheckCharacterRuntimeHealthResponse
| Field | Type | Label | Description |
|---|
| serving | bool | | |
| runtime_version | string | | |
CommitCharacterExecutionRequest
CommitCharacterExecutionResponse
GetCharacterAttributesRequest
| Field | Type | Label | Description |
|---|
| character_id | string | | |
| account_id | string | | Optional under Brain service-token auth; see GetCharacterDatasetRequest. |
GetCharacterAttributesResponse
| Field | Type | Label | Description |
|---|
| found | bool | | false → no Sirloin-owned character (Brain dual-read may fall back). |
| character_id | string | | |
| lifecycle | string | | characters.character_lifecycle (draft/training/available/blocked/rejected). |
| values | google.protobuf.Struct | | Recipe-declared schema_values. Facade projects onto load_character slots; undeclared legacy fields stay absent (undefined), never invented. |
GetCharacterDatasetRequest
GetCharacterDatasetRequest loads durable dataset object keys for media gen.
types are Kitsune onboarding image type names (e.g. FACE_FRONTAL); empty
means every generation_* role. Order of types is the response group order.
| Field | Type | Label | Description |
|---|
| character_id | string | | |
| account_id | string | | Optional when the caller is the Brain service token: Sirloin resolves the owning account. Prefer setting it when known (account-scoped reads). |
| types | string | repeated | |
GetCharacterDatasetResponse
| Field | Type | Label | Description |
|---|
| found | bool | | false → no Sirloin-owned character for this id (Brain dual-read may fall back). true → Sirloin is source of truth even when object_keys is empty. |
| object_keys | string | repeated | |
RunCharacterExecutionRequest
ValidateCharacterRecipeRequest
| Field | Type | Label | Description |
|---|
| canonical_recipe_json | bytes | | |
| recipe_digest | bytes | | |
ValidateCharacterRecipeResponse
CharacterExecutionState
| Name | Number | Description |
|---|
| CHARACTER_EXECUTION_STATE_UNSPECIFIED | 0 | |
| CHARACTER_EXECUTION_STATE_QUEUED | 1 | |
| CHARACTER_EXECUTION_STATE_RUNNING | 2 | |
| CHARACTER_EXECUTION_STATE_SUCCEEDED | 3 | |
| CHARACTER_EXECUTION_STATE_FAILED | 4 | |
| CHARACTER_EXECUTION_STATE_CANCELLED | 5 | |
KitsuneOnboardingImageType
KitsuneOnboardingImageType is the single source of truth for Kitsune
onboarding / generation reference image slots. Character generation roles
for adapter “kitsune” are ToLower(enum name), e.g. FACE_FRONTAL → face_frontal.
Brain HTTP OpenAPI and recipe generation policy must stay aligned with this
enum — do not maintain a parallel string list.
| Name | Number | Description |
|---|
| KITSUNE_ONBOARDING_IMAGE_TYPE_UNSPECIFIED | 0 | |
| FACE_FRONTAL | 1 | |
| FULL_BODY | 2 | |
| FULL_BODY_ANY | 3 | |
| FACE_FRONTAL_NSFW | 4 | |
| FULL_BODY_NSFW | 5 | |
| FULL_BODY_ANY_NSFW | 6 | |
| VAGINA_FRONTAL_NSFW | 7 | |
| VAGINA_CLOSEUP_NSFW | 8 | |
| ANUS_NSFW | 9 | |
CharacterRuntimeControlService
CharacterRuntimeControlService is implemented by Sirloin.
Acquire/Commit were built for mid-flight sync RunCharacterExecution; Bull
EXECUTE Acquires locally at wake-up and Commits from the character-completion
HTTP webhook. GetCharacterDataset / GetCharacterAttributes are the dual-read
surface Brain dials for media-generation character data (see ADR 2026-08-08).
Service-token auth is required before those reads are safe on this server.
CharacterRuntimeService
CharacterRuntimeService is implemented by Brain and invoked by Sirloin.
Brain executes provider work but owns no authoritative character state.
Top
round/v1/round.proto
InferRequest
InferRequest contains the input data and model selection for inference.
| Field | Type | Label | Description |
|---|
| model_id | string | | model_id identifies which model to use for inference. Examples: “embeddings”, “face-detection” |
| text | string | | text input for text-based models (e.g., embeddings) |
| image_base64 | string | | image_base64 input for image-based models (e.g., face detection) Base64 encoded image data. Expected formats: JPEG, PNG |
| options | string | | Optional parameters specific to the model (JSON encoded) |
InferResponse
InferResponse contains the inference results.
Errors are returned via gRPC status codes, not in the response body.
| Field | Type | Label | Description |
|---|
| output | string | | output contains the inference result as text For embeddings: JSON array of float values For face detection: JSON with bounding boxes and metadata |
| metadata | string | | metadata contains additional information about the inference (e.g., processing time, model version, etc.) as JSON |
ListModelsRequest
ListModelsRequest is currently empty but reserved for future pagination
ListModelsResponse
ListModelsResponse contains information about available models.
| Field | Type | Label | Description |
|---|
| models | ModelInfo | repeated | |
ModelInfo
ModelInfo describes a single available model.
| Field | Type | Label | Description |
|---|
| model_id | string | | model_id is the unique identifier for the model |
| name | string | | name is the human-readable name of the model |
| description | string | | description provides details about what the model does |
| input_type | string | | input_type indicates the expected input type (text, image, etc.) |
| output_type | string | | output_type indicates the output format (embeddings, json, etc.) |
| version | string | | version is the model version |
RoundService
Round Service
A universal ONNX model serving microservice that provides inference
capabilities for multiple ML models including text embeddings and
image analysis.
| Method Name | Request Type | Response Type | Description |
|---|
| Infer | InferRequest | InferResponse | Infer runs inference on the specified model with the provided input. The model is selected via model_id, and input can be either text or binary data (e.g., images). |
| ListModels | ListModelsRequest | ListModelsResponse | ListModels returns information about all available models. |
Top
sirloin/v5/billing.proto
AddPaymentMethodRequest
AddPaymentMethodRequest - vault a single-use payment method token
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (becomes Primer customer_id) |
| payment_method_token | string | | Single-use token from Primer checkout |
AddPaymentMethodResponse
AddPaymentMethodResponse returns the newly vaulted payment method
| Field | Type | Label | Description |
|---|
| payment_method | PaymentMethod | | The newly vaulted payment method |
BillingAddress
BillingAddress represents a customer’s billing address
| Field | Type | Label | Description |
|---|
| first_name | string | | |
| last_name | string | | |
| line1 | string | | Street address line 1 |
| line2 | string | optional | Street address line 2 (optional) |
| city | string | | |
| state | string | optional | State/province (optional for some countries) |
| country | string | | ISO 3166-1 alpha-2 country code |
| zip | string | optional | Postal/ZIP code (optional for some countries) |
CancelScheduledDowngradeRequest
CancelScheduledDowngradeRequest - cancel a scheduled plan change (e.g., downgrade)
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
CancelScheduledDowngradeResponse
CancelScheduledDowngradeResponse returns the updated subscription after removing scheduled changes
| Field | Type | Label | Description |
|---|
| success | bool | | Whether the scheduled change was cancelled |
| current_subscription | SubscriptionDetails | | Updated subscription details (without scheduled changes) |
CancelSubscriptionRequest
CancelSubscriptionRequest - cancel subscription at end of term
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
CancelSubscriptionResponse
CancelSubscriptionResponse returns cancellation details
| Field | Type | Label | Description |
|---|
| cancellation_effective_date | int64 | | Unix timestamp when subscription ends |
| status | string | | Subscription status after cancellation (“non_renewing”) |
| subscription_id | string | | Chargebee subscription ID |
CardDetails
CardDetails contains card-specific payment method information
| Field | Type | Label | Description |
|---|
| last4 | string | | Last 4 digits of card number |
| brand | string | | Card network (Visa, Mastercard, etc.) |
| expiry_month | string | | 2-digit expiration month |
| expiry_year | string | | 4-digit expiration year |
| cardholder_name | string | | Cardholder name (optional) |
CouponCredits
CouponCredits contains bonus credits from coupon metadata
| Field | Type | Label | Description |
|---|
| additional_images | int32 | | Bonus image credits |
| additional_characters | int32 | | Bonus character slots |
CouponInfo
CouponInfo contains coupon validation and discount details
| Field | Type | Label | Description |
|---|
| coupon_id | string | | Chargebee coupon ID |
| name | string | | Display name |
| discount_type | CouponDiscountType | | |
| discount_percentage | double | optional | For percentage coupons |
| discount_amount | int32 | optional | For fixed amount coupons (cents) |
| currency_code | string | optional | For fixed amount coupons |
| duration_type | string | | one_time, forever, limited_period |
| is_valid | bool | | Whether coupon can be applied |
| invalid_reason | string | optional | Reason if not valid |
| credits | CouponCredits | optional | Bonus credits from coupon metadata |
| raw_metadata | string | optional | Raw JSON of all coupon custom metadata |
| initial_subscription_only | bool | optional | cf_initialsubscriptiononly: coupon only for first-time subscribers |
| checkout_description | string | optional | cf_checkout_description: description for checkout display |
CreatePrimerCheckoutRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| user_email | string | | |
| item_price_id | string | | Chargebee item price ID |
| country | string | optional | Optional country code for metadata |
| coupon_code | string | optional | Optional coupon code to apply |
| test_psp | string | optional | Internal testing: override PSP via feature flag |
| payment_method_token | string | optional | Optional vaulted Primer token for MIT one-off payment |
| idempotency_key | string | optional | Required when payment_method_token is set |
CreatePrimerCheckoutResponse
| Field | Type | Label | Description |
|---|
| client_token | string | | Primer client token for frontend checkout |
| order_id | string | | Order ID (Chargebee invoice ID) |
| chargebee_customer_id | string | | |
| chargebee_subscription_id | string | | |
| chargebee_invoice_id | string | | |
| amount | int32 | | Final amount in cents (after discount) |
| currency | string | | Currency code (e.g., USD) |
| original_amount | int32 | | Original amount before discount (cents) |
| discount_amount | int32 | | Discount amount applied (cents) |
| is_zero_amount_checkout | bool | | True if 100% coupon discount (checkout complete) |
| is_scheduled_change | bool | | True if downgrade scheduled for end of term (no checkout needed) |
| scheduled_change_date | int64 | | Unix timestamp when scheduled change takes effect |
| primer_payment_id | string | optional | Primer payment ID for direct MIT one-off payments |
| is_payment_pending | bool | | True if a direct MIT payment needs async confirmation/fulfillment |
| processor | string | | Payment processor assigned to the user (e.g. “NMI”, “EMP”) |
CreateVaultingSessionRequest
CreateVaultingSessionRequest - create a Primer session for vaulting only
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Primer customer_id) |
| user_email | string | | User email for Primer |
| country | string | optional | Optional country code for payment method options |
| test_psp | string | optional | Internal testing: override PSP via feature flag |
CreateVaultingSessionResponse
CreateVaultingSessionResponse returns the Primer client token
| Field | Type | Label | Description |
|---|
| client_token | string | | Primer client token for frontend checkout |
| processor | string | | Payment processor assigned to the user (e.g. “NMI”, “EMP”) |
DeletePaymentMethodRequest
DeletePaymentMethodRequest - remove a vaulted payment method
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id for authorization |
| payment_method_token | string | | Token of payment method to delete |
DeletePaymentMethodResponse
DeletePaymentMethodResponse returns the updated payment method list
| Field | Type | Label | Description |
|---|
| payment_methods | PaymentMethod | repeated | Updated list after deletion |
DunningState
DunningState contains detailed dunning information for users with failed payments.
| Field | Type | Label | Description |
|---|
| is_in_dunning | bool | | Whether user is currently in dunning |
| access_loss_date | int64 | | Unix timestamp: when subscription will be cancelled |
| next_retry_date | int64 | | Unix timestamp: next payment attempt (0 if hard decline) |
| attempt_number | int32 | | Which retry attempt we’re on |
| max_attempts | int32 | | Total retries before cancellation |
| recovery_attempted | bool | | True if primary method changed after last failed attempt |
| last_dunning_attempt_at | int64 | | Unix timestamp: most recent failed attempt |
| primary_method_changed_at | int64 | | Unix timestamp: when primary payment method was last set |
EarnedCredits
| Field | Type | Label | Description |
|---|
| date_month | string | | Format: “YYYY-MM” |
| referrals | int32 | | |
| credits | int32 | | |
GetCurrentUsageRequest
GetCurrentUsageResponse
| Field | Type | Label | Description |
|---|
| characters_count | int32 | | |
| media_count | int32 | | |
| media_monthly_limit | int32 | | |
| remaining_credits_count | int32 | | |
| remaining_full_access_credits_count | int32 | | |
| tier | string | | |
| is_subscribed | bool | | |
| has_subscribed | bool | | |
| reimbursement_eligible | bool | | |
| cancellation_benefit_eligible | bool | | |
| referrals | Referrals | | |
| stats | Stats | | |
| is_in_dunning | bool | | True if user has unpaid renewal invoice within dunning window |
| is_non_renewing | bool | | True if subscription is cancelled but still active until term end |
| kyc_identification_status | KycIdentificationStatus | | Ondato-like identification status (Awaiting/Approved/Rejected) |
| standard_credits_count | int32 | | |
| dunning | DunningState | | Detailed dunning state (nil if not in dunning) |
| kyc_reset_eligible | bool | | |
| kyc_approved_at | int64 | | Unix timestamp: when KYC was approved (0 if not approved) |
| has_ever_created_character | bool | | True once the account has owned a character, soft-deleted ones included. characters_count answers “how many now” and drops back to zero on delete; this answers “have they ever”, which is what the 18+ rules are written against. Clients gating adult surfaces must read this, not the count. |
| has_ever_created_nsfw_character | bool | | True once the account has owned an 18+ character, soft-deleted ones included. An 18+ character cannot exist without an 18+ plan behind it, so this stands in for “has ever paid for 18+” without reading billing history. Clients use it to stop offering a first-month discount to a returning customer. |
GetPaymentMethodsRequest
GetPaymentMethodsRequest - requires user_id for Primer vault lookup
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id used as Primer customer_id |
GetPaymentMethodsResponse
GetPaymentMethodsResponse contains the list of vaulted payment methods
GetPaymentRequest
GetPaymentRequest - retrieve payment details from Primer
| Field | Type | Label | Description |
|---|
| payment_id | string | | Primer payment ID |
GetPaymentResponse
GetPaymentResponse returns payment details from Primer
GetPaymentResponse.MetadataEntry
GetSubscriptionDetailsRequest
GetSubscriptionDetailsRequest - requires user_id
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
GetSubscriptionDetailsResponse
GetSubscriptionDetailsResponse contains subscription information
| Field | Type | Label | Description |
|---|
| current_subscription | SubscriptionDetails | optional | Currently active subscription (StartDate <= now) |
| future_subscription | SubscriptionDetails | optional | Pending downgrade subscription (StartDate > now, < 1 year) |
GetTransactionsRequest
GetTransactionsRequest - requires user_id for invoice lookup
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
GetTransactionsResponse
GetTransactionsResponse contains complete transaction history
| Field | Type | Label | Description |
|---|
| transactions | Transaction | repeated | All transactions, newest first |
GetWorkflowPricingRequest
GetWorkflowPricingRequest - PUBLIC endpoint, no authentication required.
GetWorkflowPricingResponse
GetWorkflowPricingResponse contains pricing for all published workflows.
HasNsfwPurchaseRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
HasNsfwPurchaseResponse
| Field | Type | Label | Description |
|---|
| has_nsfw_purchase | bool | | |
ListProductsRequest
ListProductsRequest - PUBLIC endpoint, no authentication required
| Field | Type | Label | Description |
|---|
| currency_code | string | optional | Filter by currency (default: all) |
| product_type | ProductType | optional | Filter by type (default: all) |
| coupon_code | string | optional | Apply coupon to calculate discounted prices |
ListProductsResponse
ListProductsResponse contains all products grouped by type
| Field | Type | Label | Description |
|---|
| subscription_products | Product | repeated | Subscription plans sorted by tier |
| one_time_products | Product | repeated | One-time purchases (image packs, characters) |
PaymentMethod
PaymentMethod represents a vaulted payment method from Primer
| Field | Type | Label | Description |
|---|
| token | string | | Primer payment method token (unique identifier) |
| payment_method_type | PaymentMethodType | | Type of payment method |
| is_default | bool | | Whether this is the default payment method |
| created_at | string | | ISO 8601 timestamp |
| card_details | CardDetails | optional | Present if payment_method_type is CARD/GOOGLE_PAY/APPLE_PAY |
| description | string | optional | User-provided description |
| analytics_id | string | optional | Primer analytics ID for tracking |
PlanDetails
PlanDetails contains plan information
| Field | Type | Label | Description |
|---|
| plan_name | string | | e.g., “starter”, “ultimate”, “creator” |
| item_price_id | string | | Chargebee item_price_id |
| price | int32 | | Price in cents |
| currency | string | | ISO currency code |
| billing_period | BillingPeriod | | Monthly/Yearly |
PrimerPaymentStatusReason
PrimerPaymentStatusReason provides details about payment status
| Field | Type | Label | Description |
|---|
| type | string | | APPLICATION_ERROR, GATEWAY_REJECTED, GATEWAY_TIMEOUT, ISSUER_DECLINED |
| decline_type | string | | SOFT_DECLINE (retryable), HARD_DECLINE (permanent) |
| code | string | | Error code (e.g., INSUFFICIENT_FUNDS, EXPIRED_CARD) |
| message | string | | Human-readable error message |
Product
Product represents a single product (subscription or one-time)
| Field | Type | Label | Description |
|---|
| id | string | | Chargebee item ID (e.g., “foxy-starter-new”) |
| name | string | | Display name (e.g., “Starter”) |
| description | string | | Marketing description |
| product_type | ProductType | | SUBSCRIPTION or ONE_TIME |
| prices | ProductPrice | repeated | All price variants (multi-currency, multi-period) |
| benefits | ProductBenefits | | Credits/limits from metadata |
| is_popular | bool | | Featured/recommended flag |
| sort_order | int32 | | Display order |
| icon | string | optional | Icon identifier for frontend |
ProductBenefits
ProductBenefits represents the credits/limits from Chargebee item metadata
| Field | Type | Label | Description |
|---|
| images_monthly_limit | int32 | | Monthly image credit limit |
| character_limit | int32 | | Character slot limit |
| additional_images | int32 | | Bonus images (for one-time packs) |
| additional_characters | int32 | | Bonus characters (for one-time packs) |
| concurrent_generations | int32 | | Concurrent image generation slots |
| concurrent_video_generations | int32 | | Concurrent video generation slots |
| credit_type | CreditType | | |
ProductPrice
ProductPrice represents a single price variant for a product
| Field | Type | Label | Description |
|---|
| item_price_id | string | | Chargebee item_price_id for CreatePrimerCheckout |
| currency_code | string | | ISO currency code (e.g., “USD”, “EUR”) |
| price | int32 | | Price in minor units (cents) |
| billing_period | BillingPeriod | | MONTHLY/YEARLY for subscriptions, UNSPECIFIED for one-time |
| price_per_month | int32 | optional | For yearly plans: price / 12 (convenience field) |
| discounted_price | int32 | optional | Price after coupon (if coupon_code provided in request) |
| discount_amount | int32 | optional | Amount saved (original price - discounted price) |
ProvideCancellationBenefitRequest
ProvideCancellationBenefitResponse
ReactivateSubscriptionRequest
ReactivateSubscriptionRequest - reactivate a cancelled subscription
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
ReactivateSubscriptionResponse
ReactivateSubscriptionResponse returns reactivation details
| Field | Type | Label | Description |
|---|
| subscription_id | string | | Chargebee subscription ID |
| status | string | | Subscription status after reactivation (“active”) |
| next_billing_at | int64 | | Unix timestamp of next billing date |
Referrals
ReservePaymentAttemptRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| planned_amount_cents | int64 | | planned_amount_cents and currency do NOT affect the allow/deny decision — count quota is purely transaction-count based. They are recorded into the authorization_attempt event metadata for observability and audit trails. |
| currency | string | | |
| merchant_context | string | | merchant_context controls whether this checkout consumes the high-risk PSP quota. Only “full” records an authorization_attempt; regular/SFW checkouts are allowed without writing quota rows. |
ReservePaymentAttemptResponse
RetryDunningPaymentRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
RetryDunningPaymentResponse
SetPrimaryPaymentMethodRequest
SetPrimaryPaymentMethodRequest - set a payment method as default
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id for authorization |
| payment_method_token | string | | Token of payment method to set as default |
SetPrimaryPaymentMethodResponse
SetPrimaryPaymentMethodResponse returns the updated payment method list
| Field | Type | Label | Description |
|---|
| payment_methods | PaymentMethod | repeated | Updated list with new default |
SetReferralCodeRequest
SetReferralCodeResponse
Stats
| Field | Type | Label | Description |
|---|
| images_generated_last_30_days | int32 | | |
| videos_generated_last_30_days | int32 | | |
| top_custom_text | string | | |
SubmitPaidInvoiceRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| subscription_id | string | optional | For Primer-based payments (legacy): subscription_id to search for Primer payment by order_id |
| invoice_id | int32 | optional | For Chargebee-direct payments: invoice_id to poll for and apply credits |
| payment_id | string | optional | For Primer-based payments (preferred): direct payment_id lookup via GET /payments/{id} subscription_id is extracted from payment’s order_id field, no need to pass it separately |
SubmitPaidInvoiceResponse
SubscriptionDetails
SubscriptionDetails contains current subscription state
| Field | Type | Label | Description |
|---|
| current_plan | PlanDetails | | Current active plan |
| future_plan | PlanDetails | optional | Scheduled plan change (if any) |
| renewal_date | int64 | | Unix timestamp of next renewal (current_term_end) |
| next_billing_amount | int32 | | Next billing amount in cents |
| status | string | | active, non_renewing, cancelled, etc. |
| has_scheduled_changes | bool | | Whether changes are scheduled |
| subscription_id | string | | Chargebee subscription ID |
| activated_at | int64 | | Unix timestamp when subscription became active |
| next_billing_at | int64 | | Unix timestamp of next billing date |
| is_non_renewing | bool | | True if subscription is canceled (non_renewing status) |
Transaction
Transaction represents a single billing transaction
TransactionPaymentMethod
TransactionPaymentMethod contains payment method details for a transaction
| Field | Type | Label | Description |
|---|
| type | PaymentMethodType | | Card, Google Pay, Apple Pay, etc. |
| last4 | string | optional | Last 4 digits (for cards) |
| brand | string | optional | Card brand (Visa, Mastercard, etc.) |
UpdateBillingAddressRequest
UpdateBillingAddressRequest - update billing address in Chargebee
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
| billing_address | BillingAddress | | New billing address |
| client_token | string | optional | Primer client session token to update |
UpdateBillingAddressResponse
UpdateBillingAddressResponse returns the updated billing address
| Field | Type | Label | Description |
|---|
| billing_address | BillingAddress | | Updated billing address |
UpdateNextBillingDateForTestingRequest
UpdateNextBillingDateForTestingRequest - test helper to move renewal earlier
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user_id (Chargebee customer_id) |
| minutes | int32 | | Minutes from now for the new term end |
UpdateNextBillingDateForTestingResponse
UpdateNextBillingDateForTestingResponse returns updated subscription timing
| Field | Type | Label | Description |
|---|
| subscription_id | string | | Chargebee subscription ID |
| status | string | | Subscription status after update |
| next_billing_at | int64 | | Unix timestamp of next billing date |
ValidateCouponRequest
ValidateCouponRequest - validate a coupon code
| Field | Type | Label | Description |
|---|
| coupon_code | string | | Coupon code to validate |
| for_subscription | bool | optional | If true, validates for subscription use |
| user_id | string | optional | If provided, cleanup pending checkouts before validation |
ValidateCouponResponse
ValidateCouponResponse returns validation result
| Field | Type | Label | Description |
|---|
| valid | bool | | Whether coupon is valid for use |
| reason | string | optional | Reason if not valid (human-readable) |
| coupon | CouponInfo | optional | Coupon details if valid (for display) |
WorkflowPrice
WorkflowPrice contains pricing information for a single workflow.
A workflow is wholly SFW or NSFW, so base_price already reflects that — there
is no NSFW multiplier. Final cost: image = base_price, video = base_price ×
duration(s), carousel = base_price × fixed carousel size.
| Field | Type | Label | Description |
|---|
| workflow_name | string | | Workflow identifier (e.g. “kitsune-custom-image”) |
| display_name | string | | Human-readable name |
| base_price | int32 | | Base credit cost (per image / per second / per carousel item) |
BillingPeriod
BillingPeriod for subscription products
| Name | Number | Description |
|---|
| BILLING_PERIOD_UNSPECIFIED | 0 | |
| BILLING_PERIOD_MONTHLY | 1 | |
| BILLING_PERIOD_YEARLY | 2 | |
CouponDiscountType
CouponDiscountType represents how the discount is calculated
| Name | Number | Description |
|---|
| COUPON_DISCOUNT_TYPE_UNSPECIFIED | 0 | |
| COUPON_DISCOUNT_TYPE_PERCENTAGE | 1 | Percentage off |
| COUPON_DISCOUNT_TYPE_FIXED_AMOUNT | 2 | Fixed amount off |
CreditType
CreditType distinguishes between standard (SFW-only) and full-access (SFW+NSFW) credits
| Name | Number | Description |
|---|
| CREDIT_TYPE_UNSPECIFIED | 0 | |
| CREDIT_TYPE_STANDARD | 1 | |
| CREDIT_TYPE_FULL_ACCESS | 2 | |
KycIdentificationStatus
KycIdentificationStatus matches Ondato’s identification status semantics.
| Name | Number | Description |
|---|
| KYC_IDENTIFICATION_STATUS_UNSPECIFIED | 0 | |
| KYC_IDENTIFICATION_STATUS_AWAITING | 1 | |
| KYC_IDENTIFICATION_STATUS_APPROVED | 2 | |
| KYC_IDENTIFICATION_STATUS_REJECTED | 3 | |
PaymentMethodType
PaymentMethodType represents the type of vaulted payment method
| Name | Number | Description |
|---|
| PAYMENT_METHOD_TYPE_UNSPECIFIED | 0 | |
| PAYMENT_METHOD_TYPE_CARD | 1 | |
| PAYMENT_METHOD_TYPE_GOOGLE_PAY | 2 | |
| PAYMENT_METHOD_TYPE_APPLE_PAY | 3 | |
ProductType
ProductType distinguishes between subscription plans and one-time purchases
| Name | Number | Description |
|---|
| PRODUCT_TYPE_UNSPECIFIED | 0 | |
| PRODUCT_TYPE_SUBSCRIPTION | 1 | Recurring subscription plan |
| PRODUCT_TYPE_ONE_TIME | 2 | One-time purchase (image packs, extra characters) |
RetryDunningPaymentStatus
| Name | Number | Description |
|---|
| RETRY_DUNNING_PAYMENT_STATUS_UNSPECIFIED | 0 | |
| RETRY_DUNNING_PAYMENT_STATUS_SUCCEEDED | 1 | |
| RETRY_DUNNING_PAYMENT_STATUS_PROCESSING | 2 | |
| RETRY_DUNNING_PAYMENT_STATUS_ALREADY_PAID | 3 | |
| RETRY_DUNNING_PAYMENT_STATUS_NOT_IN_DUNNING | 4 | |
| RETRY_DUNNING_PAYMENT_STATUS_NO_PAYMENT_METHOD | 5 | |
| RETRY_DUNNING_PAYMENT_STATUS_FAILED_RETRYABLE | 6 | |
| RETRY_DUNNING_PAYMENT_STATUS_FAILED_HARD_DECLINE | 7 | |
| RETRY_DUNNING_PAYMENT_STATUS_BLOCKED_VELOCITY | 8 | |
RiskAction
RiskAction represents a client-side behavioral risk signal.
| Name | Number | Description |
|---|
| RISK_ACTION_UNSPECIFIED | 0 | |
| RISK_ACTION_SHORT_APP_TIME | 1 | User is using the app for less than MIN_APP_TIME_MS |
| RISK_ACTION_NO_POINTER_INTERACTION | 2 | No pointer/mouse click or move |
| RISK_ACTION_NO_SCROLL | 3 | No scroll interaction yet |
TransactionStatus
TransactionStatus represents the status of a transaction
| Name | Number | Description |
|---|
| TRANSACTION_STATUS_UNSPECIFIED | 0 | |
| TRANSACTION_STATUS_SUCCESS | 1 | Payment successful |
| TRANSACTION_STATUS_PENDING | 2 | Payment pending |
| TRANSACTION_STATUS_FAILED | 3 | Payment failed |
| TRANSACTION_STATUS_VOIDED | 4 | Invoice voided |
TransactionType
TransactionType represents the type of billing transaction
| Name | Number | Description |
|---|
| TRANSACTION_TYPE_UNSPECIFIED | 0 | |
| TRANSACTION_TYPE_PURCHASE | 1 | New subscription or renewal payment |
| TRANSACTION_TYPE_REFUND | 2 | Refund issued |
| TRANSACTION_TYPE_CREDIT_NOTE | 3 | Credit note adjustment |
BillingService
Billing Service
Handles all billing-related operations including subscriptions, payments,
products, and transactions.
Usage & Credits
Top
sirloin/v5/character_common.proto
CharacterAssetReference
| Field | Type | Label | Description |
|---|
| asset_id | string | | |
| digest | string | | |
| media_type | string | | |
| state | string | | |
| object_key | string | | Account-authorized stable object reference. Consumers resolve it through their local media adapter; it is not a public URL or bearer credential. |
| ordinal | int32 | | |
| display_name | string | | |
| tags | string | repeated | |
| access_url | string | | Short-lived read credential resolved at request time. It is never stored. |
| scope | string | | Closed policy enum as a string: upload |
| role | string | | Slot name inside scope. |
CharacterCapabilityLayer
CharacterCapabilityLayer is one capability the character carries. The key is
an open vocabulary so a new tier is a data change; “adult” is the only key
with an enforcement path today.
RequestMetadata carries replay and optimistic-concurrency inputs. Trusted
internal callers provide account and actor identity on the owning request.
CharacterLifecycle
A character has two independent axes. CharacterLifecycle is where it is in
its own life; CharacterCapabilityLayer is what it is permitted to do. There is
deliberately no ADULT_ACTIVE lifecycle state: 18+ is a layer, which is what
lets a further tier ship as data rather than as a new state.
| Name | Number | Description |
|---|
| CHARACTER_LIFECYCLE_UNSPECIFIED | 0 | |
| CHARACTER_LIFECYCLE_DRAFT | 1 | |
| CHARACTER_LIFECYCLE_PENDING | 2 | |
| CHARACTER_LIFECYCLE_TRAINING | 3 | |
| CHARACTER_LIFECYCLE_AVAILABLE | 4 | |
| CHARACTER_LIFECYCLE_BLOCKED | 5 | |
| CHARACTER_LIFECYCLE_REJECTED | 6 | |
CharacterOperationStatus
| Name | Number | Description |
|---|
| CHARACTER_OPERATION_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_OPERATION_STATUS_PENDING | 1 | |
| CHARACTER_OPERATION_STATUS_RUNNING | 2 | |
| CHARACTER_OPERATION_STATUS_ACTION_REQUIRED | 3 | |
| CHARACTER_OPERATION_STATUS_RETRYING | 4 | |
| CHARACTER_OPERATION_STATUS_SUCCEEDED | 5 | |
| CHARACTER_OPERATION_STATUS_REJECTED | 6 | |
| CHARACTER_OPERATION_STATUS_FAILED | 7 | |
| CHARACTER_OPERATION_STATUS_CANCELED | 8 | |
| CHARACTER_OPERATION_STATUS_EXPIRED | 9 | |
CharacterVerificationState
| Name | Number | Description |
|---|
| CHARACTER_VERIFICATION_STATE_UNSPECIFIED | 0 | |
| CHARACTER_VERIFICATION_STATE_INSTANT | 1 | |
| CHARACTER_VERIFICATION_STATE_NEEDS_REVIEW | 2 | |
| CHARACTER_VERIFICATION_STATE_IN_REVIEW | 3 | |
| CHARACTER_VERIFICATION_STATE_NOT_APPROVED | 4 | |
| CHARACTER_VERIFICATION_STATE_APPROVED | 5 | |
Top
sirloin/v5/character_capability.proto
CharacterAdultState
CharacterAdultState is the stored adult capability of one character.
adult_enabled is the slot authority. Whether the capability may currently be
used is the derived CharacterCapabilityLayer.enabled on the projection, which
reads false while a dataset change holds the character in review.
| Field | Type | Label | Description |
|---|
| character_id | string | | |
| adult_enabled | bool | | |
| identity_anchor | string | optional | The identity holding this character’s single adult slot. Absent while the capability is off. |
| selfie_reset_count | uint32 | | |
EnableCharacterAdultCapabilityRequest
| Field | Type | Label | Description |
|---|
| metadata | RequestMetadata | | |
| user_id | string | | |
| character_id | string | | |
| identity_anchor | string | | The identity this character’s adult slot is bound to, one per account. Sirloin enforces the slot. It does not check that the anchor came from a completed verification; that binding is the caller’s until the verification ladder (FOXY-621) lands. |
EnableCharacterAdultCapabilityResponse
IncrementCharacterSelfieResetCountRequest
IncrementCharacterSelfieResetCountResponse
CharacterCapabilityService
CharacterCapabilityService is the write surface for the capability axis.
It is separate from the projection service because enabling 18+ binds an
identity to a character and holds the account’s single slot for it: the
authorization story is the compliance one, not the one that governs ordinary
roster reads and edits.
Both RPCs are replay-safe on RequestMetadata.client_request_id, and the reason
on that metadata is required here: every call lands in the character event log.
Top
tbone/v1/character_recipe.proto
CharacterAction
CharacterActionBindings
CharacterAssetBinding
| Field | Type | Label | Description |
|---|
| input_key | string | | |
| field_key | string | optional | field_key binds an upload field; scope+role binds durable saved assets. |
| min_count | uint32 | | |
| max_count | uint32 | | |
| content_types | string | repeated | |
| scope | string | optional | Closed policy enum as a string: upload |
| role | string | optional | Slot name inside scope; recipe-declared, ^[a-z][a-z0-9_-]{0,63}$. |
CharacterAssetOutput
CharacterAssetOutput is the recipe-owned cardinality contract for durable
runtime assets. It is universal across questionnaire, upload, and mixed
character recipes. Scope carries policy (ADR 2026-08-11); role is the slot
name inside that scope. Kitsune generation references use bare roles
face_frontal / full_body / full_body_any under scope generation — never a
generation_ prefix.
| Field | Type | Label | Description |
|---|
| asset_kind | string | | |
| min_count | uint32 | | |
| max_count | uint32 | | |
| scope | string | | Closed policy enum as a string: upload |
| role | string | | Slot name inside scope; recipe-declared, ^[a-z][a-z0-9_-]{0,63}$. |
CharacterBillingPolicy
CharacterBillingPolicy prices one repeatable action, so “first re-roll free,
then 10 credits” is recipe data rather than code. Sirloin owns enforcement:
it counts uses and bounds the free allowance, and a run that fails hands its
use back.
| Field | Type | Label | Description |
|---|
| id | string | | |
| credits | int64 | | |
| included_uses | uint32 | | Runs of this policy that cost nothing, counted per character across every action that shares the policy. Sirloin caps it, so a recipe cannot write itself an unlimited free tier; the first character’s provisioning credit is code-owned and cannot be granted here at all. |
CharacterCondition
CharacterConditionGroup
CharacterEqualsCondition
| Field | Type | Label | Description |
|---|
| path | string | | |
| value | google.protobuf.Value | | |
CharacterExistsCondition
| Field | Type | Label | Description |
|---|
| path | string | | |
CharacterField
CharacterLocalDataDefinition
| Field | Type | Label | Description |
|---|
| key | string | | |
| default_value | google.protobuf.Value | | |
CharacterManagement
CharacterManagement defines ordered cards and their focused edit flows.
Draft navigation stays in the client; only a terminal SAVE action is sent to
Sirloin.
CharacterManagementSection
CharacterManagementSummary
CharacterManagementSummaryAssetRef
CharacterManagementSummaryAssetRef is a bound asset identified by the
scope+role pair from ADR 2026-08-11 (not the retired flat role_key).
| Field | Type | Label | Description |
|---|
| scope | string | | Closed policy enum as a string: upload |
| role | string | | Slot name inside scope; recipe-declared, ^[a-z][a-z0-9_-]{0,63}$. |
CharacterManagementSummaryBinding
CharacterOption
| Field | Type | Label | Description |
|---|
| value | google.protobuf.Value | | |
| label | string | | |
| description | string | | |
| media | CharacterMediaReference | | |
| payload | google.protobuf.Struct | | What picking this option does to a regeneration, as data the workflow interprets. Adding an attribute to the catalog is a publish rather than a release because this travels with the option that offers it. |
CharacterPresentation
CharacterRecipe
CharacterRecipe is the code-owned envelope for data-owned character flows.
It deliberately has no VI/RI or real/visual discriminator. Creation method
provenance is the pinned recipe key, version, and digest.
CharacterRecipeCatalogEntry
CharacterStage
CharacterStageContentBlock
Content blocks are ordered presentation data. They never become session or
character values.
CharacterStageFlow
| Field | Type | Label | Description |
|---|
| entry_stage_id | string | | |
| stages | CharacterStage | repeated | |
| local_data | CharacterLocalDataDefinition | repeated | Client-owned temporary values. They never participate in server conditions, transitions, workflow inputs, billing, or persisted session state. |
CharacterTransition
| Field | Type | Label | Description |
|---|
| kind | CharacterTransitionKind | | |
| stage_id | string | optional | |
| return_to_caller_if_present | bool | | Reuse a local form as an editor: return through server history when it has a caller, otherwise apply the declared NEXT transition. |
CharacterValueBinding
| Field | Type | Label | Description |
|---|
| input_key | string | | |
| field_key | string | | |
| fixed_value | google.protobuf.Value | | |
| required | bool | | |
CharacterWorkflow
CharacterWorkflow is the recipe-side pin to a Brain-owned compute graph.
The full node graph lives in Brain’s workflow table; the recipe stores only
the immutable pin + the contract projection Sirloin needs for session,
billing, and commit validation.
| Field | Type | Label | Description |
|---|
| id | string | | |
| purpose | string | | |
| input_bindings | google.protobuf.Struct | | |
| output_schema | google.protobuf.Struct | | |
| asset_outputs | CharacterAssetOutput | repeated | |
| brain_workflow_id | string | | UUID of a published Brain workflow row. Required. |
| graph_digest | string | | Lowercase hex SHA-256 of the pinned graph canonical bytes at recipe publish. |
| contract_digest | string | optional | Lowercase hex SHA-256 of the contract projection (purpose + input_bindings + output_schema + asset_outputs). Optional; recommended for drift checks. |
CharacterActionKind
| Name | Number | Description |
|---|
| CHARACTER_ACTION_KIND_UNSPECIFIED | 0 | |
| CHARACTER_ACTION_KIND_SAVE | 1 | |
| CHARACTER_ACTION_KIND_UPLOAD | 2 | |
| CHARACTER_ACTION_KIND_EXECUTE | 3 | |
| CHARACTER_ACTION_KIND_SELECT_ASSET | 4 | |
| CHARACTER_ACTION_KIND_AUTHORIZE | 5 | |
| CHARACTER_ACTION_KIND_LOCAL | 6 | LOCAL values are persisted by the client (for example, in IndexedDB) and are not persisted in the Sirloin session. The action is still sent to Sirloin, which applies the declared transition and remains authoritative for the current stage and visited-stage history. |
CharacterActionRole
| Name | Number | Description |
|---|
| CHARACTER_ACTION_ROLE_UNSPECIFIED | 0 | |
| CHARACTER_ACTION_ROLE_PRIMARY | 1 | |
| CHARACTER_ACTION_ROLE_SECONDARY | 2 | |
| CHARACTER_ACTION_ROLE_CHOICE | 3 | |
| CHARACTER_ACTION_ROLE_BACK | 4 | |
| CHARACTER_ACTION_ROLE_AUTOMATIC | 5 | |
CharacterControlKind
| Name | Number | Description |
|---|
| CHARACTER_CONTROL_KIND_UNSPECIFIED | 0 | |
| CHARACTER_CONTROL_KIND_OPTION_GRID | 1 | |
| CHARACTER_CONTROL_KIND_CHIPS | 2 | |
| CHARACTER_CONTROL_KIND_COLOR_PICKER | 3 | |
| CHARACTER_CONTROL_KIND_MULTI_SELECT | 4 | |
| CHARACTER_CONTROL_KIND_TEXT | 5 | |
| CHARACTER_CONTROL_KIND_MEDIA_UPLOAD | 6 | |
CharacterEntitlementKind
| Name | Number | Description |
|---|
| CHARACTER_ENTITLEMENT_KIND_UNSPECIFIED | 0 | |
| CHARACTER_ENTITLEMENT_KIND_ACTIVE_SUBSCRIPTION | 1 | |
CharacterStageContentKind
| Name | Number | Description |
|---|
| CHARACTER_STAGE_CONTENT_KIND_UNSPECIFIED | 0 | |
| CHARACTER_STAGE_CONTENT_KIND_TEXT | 1 | |
| CHARACTER_STAGE_CONTENT_KIND_NOTICE | 2 | |
| CHARACTER_STAGE_CONTENT_KIND_MEDIA | 3 | |
CharacterStageKind
| Name | Number | Description |
|---|
| CHARACTER_STAGE_KIND_UNSPECIFIED | 0 | |
| CHARACTER_STAGE_KIND_FORM | 1 | |
| CHARACTER_STAGE_KIND_UPLOAD | 2 | |
| CHARACTER_STAGE_KIND_REVIEW | 3 | |
| CHARACTER_STAGE_KIND_ASSET_PICKER | 4 | |
| CHARACTER_STAGE_KIND_CONFIRMATION | 5 | |
| CHARACTER_STAGE_KIND_STATUS | 6 | |
CharacterTransitionKind
| Name | Number | Description |
|---|
| CHARACTER_TRANSITION_KIND_UNSPECIFIED | 0 | |
| CHARACTER_TRANSITION_KIND_STAY | 1 | |
| CHARACTER_TRANSITION_KIND_NEXT | 2 | |
| CHARACTER_TRANSITION_KIND_BACK | 3 | |
| CHARACTER_TRANSITION_KIND_STAGE | 4 | |
Top
sirloin/v5/character_recipe.proto
CharacterRecipeRoute
CharacterRecipeValidationIssue
CharacterRecipeVersion
DeleteCharacterRecipeDraftRequest
DeleteCharacterRecipeDraftResponse
| Field | Type | Label | Description |
|---|
| replayed | bool | | |
GetCharacterRecipeRequest
| Field | Type | Label | Description |
|---|
| route_key | string | | |
| version_id | string | | |
| include_editor_state | bool | | Admin-gated recipe tooling may request draft and unpublished state. |
GetCharacterRecipeResponse
ListCharacterRecipesRequest
| Field | Type | Label | Description |
|---|
| include_editor_state | bool | | Admin-gated recipe tooling may request draft and unpublished state. |
ListCharacterRecipesResponse
PublishCharacterRecipeRequest
PublishCharacterRecipeResponse
PutCharacterRecipeDraftRequest
PutCharacterRecipeDraftResponse
RollbackCharacterRecipeRouteRequest
RollbackCharacterRecipeRouteResponse
CharacterRecipeVersionStatus
| Name | Number | Description |
|---|
| CHARACTER_RECIPE_VERSION_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_RECIPE_VERSION_STATUS_DRAFT | 1 | |
| CHARACTER_RECIPE_VERSION_STATUS_PUBLISHED | 2 | |
CharacterRecipeService
CharacterRecipeService stores T-Bone-authored drafts and immutable
published recipes. Callers are trusted services on the private gRPC mesh.
Top
sirloin/v5/character_session.proto
ApplyCharacterSessionActionRequest
ApplyCharacterSessionActionResponse
CharacterAssetSelectionInput remains recipe-neutral: the recipe result
names the group while Sirloin verifies every selected asset binding.
| Field | Type | Label | Description |
|---|
| group_key | string | | |
| asset_ids | string | repeated | |
CharacterSession
CharacterSessionAction
| Field | Type | Label | Description |
|---|
| action_id | string | | |
| available | bool | | |
| unavailable_reason | string | optional | |
CharacterSessionOperation
CharacterSessionValuesInput is used by recipe-defined form actions. Sirloin
accepts only fields referenced by the pinned action’s declared bindings.
| Field | Type | Label | Description |
|---|
| values_json | bytes | | |
CharacterUploadFinalizeInput identifies a previously prepared asset. The
service downloads and measures the object before storage accepts it.
| Field | Type | Label | Description |
|---|
| asset_id | string | | |
CharacterUploadPrepareInput starts a bounded upload for one media field in
the pinned current stage. Declared metadata is re-verified on finalize.
CharacterUploadTicket
DiscardCharacterSessionRequest
DiscardCharacterSessionResponse
GetCharacterSessionRequest
GetCharacterSessionResponse
StartCharacterSessionRequest
StartCharacterSessionResponse
CharacterSessionStatus
| Name | Number | Description |
|---|
| CHARACTER_SESSION_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_SESSION_STATUS_ACTIVE | 1 | |
| CHARACTER_SESSION_STATUS_RUNNING | 2 | |
| CHARACTER_SESSION_STATUS_COMPLETED | 3 | |
| CHARACTER_SESSION_STATUS_FAILED | 4 | |
CharacterSessionService
CharacterSessionService drives every recipe-defined creation flow through
the same durable character-backed session surface.
Top
sirloin/v5/character_projection.proto
ApplyCharacterMutationRequest
ApplyCharacterMutationResponse
CharacterManagementSectionView
CharacterProjection
GetCharacterProjectionRequest
GetCharacterProjectionResponse
ListCharacterRosterProjectionRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
ListCharacterRosterProjectionResponse
ListCharacterRosterProjectionResponse.CompletedSessionCountsByRouteKeyEntry
ListCharacterRosterProjectionResponse.RecipesByVersionIdEntry
CharacterManagementSectionStatus
| Name | Number | Description |
|---|
| CHARACTER_MANAGEMENT_SECTION_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_MANAGEMENT_SECTION_STATUS_READY | 1 | |
| CHARACTER_MANAGEMENT_SECTION_STATUS_EMPTY | 2 | |
| CHARACTER_MANAGEMENT_SECTION_STATUS_UNAVAILABLE | 3 | |
CharacterProjectionService
Top
sirloin/v5/sirloin.proto
Character
Character contains the details of a character.
CharacterDatasetImage
Collection
Collection is a user-owned, named grouping of media items (FOXY-363).
| Field | Type | Label | Description |
|---|
| collection_id | string | | |
| user_id | string | | |
| name | string | | |
| description | string | optional | |
| is_public | bool | | |
| created_at | string | | |
| updated_at | string | | |
| media_count | int32 | | media_count is the number of media items in the collection. |
| cover_url | string | optional | cover_url is a preview image (the most recently added item), if any. |
| Field | Type | Label | Description |
|---|
| parent_media_id | string | | Visible parent media row created when the generation request started. |
| execution_id | string | | Workflow execution ID returned at dispatch time; used for idempotency and correlation with the parent media row. |
| workflow_name | string | | Workflow storage name expected on the parent media row. |
| status | WorkflowMediaCompletionStatus | | Final workflow status; succeeded requires at least one output. |
| outputs | WorkflowMediaOutput | repeated | Generated media outputs to materialize as child rows after completion. |
| error | string | | Failure detail for diagnostics when status is failed. |
ContentDumpAvailability
How much of one media type the pool could actually supply.
Per type because the shortfall is reported per type (“only 7 new photos
left”); a single total cannot say which type came up short.
| Field | Type | Label | Description |
|---|
| media_type | MediaType | | |
| requested | int32 | | |
| available | int32 | | |
| search | ContentDumpSearch | | How the search for this media type went. Sirloin logs the same numbers server-side; they travel so a client can say why a dump came up short in its own console, where the person seeing the thin result is looking. |
Diagnostic only — nothing here changes what is offered or charged. |
ContentDumpPick
One example a dump would run, with what it will cost.
An id rather than the example itself: the dump never shows a user its picks,
and dispatch re-reads each row from this id, so serialising the example here
would be work discarded on every keystroke of a debounced quote.
ContentDumpSearch
What one media type’s pool walk cost and found. A short result has several
causes that look identical from outside: the categories hold nothing recent,
the user has already been given everything in them, or the examples exist but
cannot be dispatched. These separate them.
| Field | Type | Label | Description |
|---|
| weeks_reached | int32 | | How far back the window had to open. Hitting the 52-week cap means the search ran out of road rather than out of appetite. |
| examples_scanned | int32 | | How far down the ranking the search read inside that window — the number of top-ranked examples the last query asked for, not a rung number. 50 means it read the top 50 and stopped; 200 means it went four times deeper looking for something usable. |
| queries | int32 | | Database round trips the walk cost. |
| considered | int32 | | Every distinct candidate seen, before the dispatchability check. |
| undispatchable | int32 | | How many of those dispatch would have refused. A large number here with a small result means the pool is there but unusable — a content problem rather than a thin one. |
| already_dumped | int32 | | Examples withheld because this user already received them from a dump. |
CopyReferenceDatasetImageRequest
CopyReferenceDatasetImageRequest carries the source path of an existing
dataset image and the character it should be copied into.
CopyReferenceDatasetImageResponse
CopyReferenceDatasetImageResponse returns the new collection path on the
target character. The caller is expected to follow up with
VerifyCharacterReferenceDatasetImage on this path.
| Field | Type | Label | Description |
|---|
| target_path | string | | |
CreateCharacterRequest
CreateCharacterRequest contains the user_id of the user and the character
details.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| gender | Gender | | |
| character_name | string | optional | |
| character_instagram_handle | string | optional | |
| character_twitter_handle | string | optional | |
| character_reference_id | string | optional | |
| character_model_type | CharacterModelType | optional | Deprecated. Deprecated: Defaults to kitsune. |
| selected_pack_id | string | optional | |
| selected_example_id | string | optional | |
| is_nsfw | bool | | |
| character_foxy_handle | string | optional | |
| is_custom_vi | bool | | |
CreateCharacterResponse
CreateCharacterResponse is returned when a character is created.
| Field | Type | Label | Description |
|---|
| character_id | string | | |
CreateCollectionRequest
CreateCollectionResponse
| Field | Type | Label | Description |
|---|
| user_id | string | | User that owns the hidden input media record. |
| character_id | string | | Character the eventual workflow generation belongs to. |
| media_type | MediaType | | Type of input media to upload; currently image or video. |
| mime_type | string | | Client-provided MIME type used to validate the upload and choose extension. |
| file_name | string | | Original file name for diagnostics; storage paths are generated server-side. |
| catalog_item_id | string | | Generation catalog item whose input contract requested this upload. |
| input_key | string | | Normalized workflow input key this upload will satisfy. |
| Field | Type | Label | Description |
|---|
| media_id | string | | Hidden media.media ID to pass in GenerateMedia.generation_input_media after the client PUT succeeds. The row is not marked AVAILABLE until GenerateMedia confirms the object exists in storage. |
| upload_url | string | | Presigned S3 PUT URL where the client uploads the input bytes. |
| object_path | string | | Durable S3 object key persisted on the hidden media row for replay. |
DeleteCharacterReferenceDatasetImageRequest
DeleteCharacterReferenceDatasetImageRequest contains the user_id,
character_id, and path of the reference dataset image to delete.
DeleteCharacterReferenceDatasetImageResponse
DeleteCharacterReferenceDatasetImageResponse is returned when the reference
dataset image is deleted.
DeleteCharacterRequest
DeleteCharacterRequest contains the user_id and character_id of the
character to delete.
DeleteCharacterResponse
DeleteCharacterResponse is returned when a character is deleted.
DeleteCollectionRequest
DeleteCollectionResponse
Outcome of one example in a batch. ok false is an expected result, not a
transport error: the example could not start (unresolvable workflow,
insufficient credits, past-due payment) while the rest of the batch ran.
| Field | Type | Label | Description |
|---|
| example_id | string | | |
| ok | bool | | |
| error | string | | Stable, client-safe reason when ok is false. Never carries upstream detail. |
| media | Media | repeated | Media rows created for this example. Empty when ok is false. |
| Field | Type | Label | Description |
|---|
| user_id | string | | Owner of the generations and of the character. |
| character_id | string | | Character every example in the batch generates for. |
| example_id | string | repeated | Examples to run, in the order the caller wants them reported back. |
| batch_id | string | optional | Groups the resulting media rows. See GenerateMediaRequest.batch_id. |
| generation_surface | GenerationSurface | optional | Marks every row this batch creates. See GenerateMediaRequest.generation_surface — set once here rather than per item, since a batch comes from exactly one surface. |
GenerateMediaRequest contains the user_id, character_id, and optional
media_pack_id and custom_text.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| custom_text | string | optional | |
| example_id | string | optional | |
| video_duration | int32 | optional | Duration in seconds for video media |
| source_media_id | string | optional | |
| video_prompt | string | optional | Prompt for video generation |
| count | int32 | optional | Number of media items to generate, defaults to 1 |
| aspect_ratio | AspectRatio | optional | |
| with_audio | bool | optional | If true, the media will have audio |
| is_nsfw | bool | optional | Whether the generated media should be NSFW |
| media_type | MediaType | optional | Type of media to generate |
| workflow_name | string | optional | Workflow name for pricing + dispatch (internal only) |
| generation_catalog_id | string | optional | App-facing catalog item ID for workflow-backed generation. Sirloin resolves this to workflow_name so clients do not depend on workflow storage names. |
| generation_inputs_json | string | optional | JSON object of scalar workflow inputs keyed by normalized contract input name. Sirloin merges hidden upload references into this object. |
| generation_input_media | GenerationInputMedia | repeated | Hidden uploaded media inputs created by CreateMediaInputUpload and passed into the workflow execution payload. Sirloin verifies each hidden upload exists in storage before marking it AVAILABLE and dispatching generation. |
| generation_axes | GenerationCatalogAxisValue | repeated | Selected axis tuple for faceted catalog items. Sirloin resolves generation_catalog_id (the family id) plus these axes to a single workflow_name before dispatch. |
| batch_id | string | optional | Groups the media rows produced by one multi-select submit, so a batch can be reassembled from the rows themselves instead of inferred from insert timestamps. Absent on single generations. |
Must be a UUID: it is stored in a uuid column, and a malformed or nil value is logged and dropped rather than rejected, since losing the grouping must not cost the caller its generation. Sirloin resolves it against nothing — it only has to be unique per submit. |
| generation_surface | GenerationSurface | optional | Which surface asked for this generation, when that is not an ordinary create flow. Recorded on the media row so a surface can be excluded from popularity rankings and counted afterwards.
Deliberately not folded into request_tier: that field carries the billing plan and is matched by substring in the worker throttle, so a surface marker inside it would silently change concurrency limits. |
GenerateMediaResponse contains the media_id and media_estimated_wait_time.
| Field | Type | Label | Description |
|---|
| media | Media | repeated | |
GenerationCatalogAxis
GenerationCatalogAxis is a family-level filter/identifier.
GenerationCatalogAxisOption
GenerationCatalogAxisOption is one selectable value of an axis.
| Field | Type | Label | Description |
|---|
| value | string | | Canonical axis value, e.g. “likeness”. |
| display_name | string | | User-facing label for the option. |
| available | bool | | False when no variant covers this value (a grid hole). |
| unavailable_reasons | string | repeated | Reasons this option is present but not selectable. |
| description | string | | One-line description shown under the option name. |
| nsfw_description | string | optional | NSFW-mode variant of description. Clients show it instead of description while the family’s is_nsfw axis is selected “true”; unset means no NSFW-specific copy and description applies in both modes. |
GenerationCatalogAxisValue
GenerationCatalogAxisValue is one (axis_key, value) pair.
GenerationCatalogItem
| Field | Type | Label | Description |
|---|
| id | string | | Stable Sirloin catalog item ID used by GenerateMedia. |
| name | string | | Internal workflow storage name, included for operator diagnostics. |
| display_name | string | | User-facing generation mode label derived from the published workflow. |
| description | string | | User-facing workflow description when provided by workflow authors. |
| contract_json | string | | Normalized media-generation contract JSON with renderable inputs, outputs, compatibility flags, and warnings derived from the published workflow. |
| available | bool | | True when Sirloin can dispatch and app clients can render the contract. |
| unavailable_reasons | string | repeated | Reasons the workflow is published but unavailable in app generation UIs. |
| price | GenerationCatalogPrice | | Workflow-defined price with Sirloin fallback defaults filled in. |
| axes | GenerationCatalogAxis | repeated | Family-level filter/identifier axes for faceted selection. Empty for singleton (non-faceted) catalog items. |
| variants | GenerationCatalogVariant | repeated | Concrete workflow variants addressed by an axis tuple. Empty for singletons. |
| is_nsfw | bool | optional | Server-resolved 18+ rating derived from the workflow’s explicitness level. Meaningful for singleton items (no variants); faceted items carry the rating per variant. Authoritative over any client-side axis derivation. Optional so clients can distinguish unset (older server) from false and fall back to axis derivation. |
| show_on_create_page | bool | | Fennec-authored switch for whether the create page shows this family’s feature tile. Display-only and pass-through: Sirloin never filters on it, a hidden family still resolves and dispatches, and unpublishing the family remains the hard kill switch. Only the newer create-page surfaces read it. |
GenerationCatalogPrice
| Field | Type | Label | Description |
|---|
| base_price | int32 | | Base credit cost. A workflow is wholly SFW or NSFW, so this already reflects the rating (no NSFW multiplier). Final cost: image = base_price, video = base_price × duration(s), carousel = base_price × carousel size. |
GenerationCatalogVariant
GenerationCatalogVariant is a family plus an axis tuple resolving to one
concrete workflow.
| Field | Type | Label | Description |
|---|
| axis_values | GenerationCatalogAxisValue | repeated | The axis tuple that selects this variant. |
| contract_json | string | | Normalized media-generation contract JSON with axis keys already stripped. |
| available | bool | | True when Sirloin can dispatch and clients can render this variant. |
| unavailable_reasons | string | repeated | Reasons this variant is published but unavailable. |
| price | GenerationCatalogPrice | | Workflow-defined price for this variant. |
| workflow_name | string | | Concrete brain workflow name this variant resolves to. Lets a client map a standalone example (authored with no family_key) back to its workflow’s contract even when the catalog collapsed that workflow into this family, so the example can dispatch the concrete workflow by name (empty axes). |
| is_nsfw | bool | optional | Server-resolved 18+ rating derived from the member workflow’s explicitness level. Authoritative over the is_nsfw axis value: it stays correct even for families with no is_nsfw axis (e.g. all-NSFW families). Optional so clients can distinguish unset (older server) from false and fall back to axis derivation. |
| Field | Type | Label | Description |
|---|
| input_key | string | | Normalized workflow contract input key this media should satisfy. |
| media_id | string | | Hidden media.media ID returned by CreateMediaInputUpload. GenerateMedia fails precondition if the referenced upload object is not present in storage yet. |
| media_type | MediaType | | Media type of the uploaded input; currently image or video. |
GetCharacterReferenceDatasetUploadURLsRequest
GetCharacterReferenceDatasetUploadURLsRequest contains the user_id and
character_id of the character to get signed URLs for.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| prefix | string | | |
| amount | int32 | optional | |
| prefixes | string | repeated | Optional prefixes for multiple images |
GetCharacterReferenceDatasetUploadURLsResponse
GetCharacterReferenceDatasetUploadURLsResponse contains the signed URLs to
upload reference dataset images.
GetCharacterReferenceImageUploadURLRequest
GetCharacterReferenceImageUploadURLRequest contains the user_id and
character_id of the character to get a signed URL for.
GetCharacterReferenceImageUploadURLResponse
GetCharacterReferenceImageUploadURLResponse contains the signed URL to upload
a reference image.
| Field | Type | Label | Description |
|---|
| character_reference_image_upload_url | string | | |
GetCustomViEvidenceUploadURLRequest
GetCustomViEvidenceUploadURLRequest carries the user, target character, and
the file extension to suffix the generated object key with.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| file_extension | string | | File extension without leading dot (e.g. “png”, “pdf”). |
GetCustomViEvidenceUploadURLResponse
GetCustomViEvidenceUploadURLResponse returns the presigned PUT URL and the
fully-qualified object path the FE should later attach to the character.
GetInstagramProfileRequest
GetInstagramProfileRequest contains the Instagram handle to look up.
| Field | Type | Label | Description |
|---|
| handle | string | | |
GetInstagramProfileResponse
GetInstagramProfileResponse contains the public Instagram profile data.
| Field | Type | Label | Description |
|---|
| display_name | string | | |
| profile_image_base64 | string | | |
| is_private | bool | | |
GetShopCharacterRequest
GetShopCharacterResponse
GetUserProfileRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
GetUserProfileResponse
ListAllMediaRequest lists all of a user’s media across every character.
Mirrors ListMediaRequest minus character_id (cross-character gallery).
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| media_ids | string | repeated | |
| media_statuses | MediaStatus | repeated | |
| page | int32 | | |
| limit | int32 | | |
| filter | ListMediaFilter | | |
| skip_total | bool | | |
| collection_id | string | optional | collection_id, when set, restricts results to the media in that collection (FOXY-363). The collection must belong to the requesting user. |
| character_id | string | optional | character_id, when set, restricts results to a single character — the cross-character gallery’s “Characters” filter (FOXY-360). |
ListAvailableCharactersRequest
ListAvailableCharactersResponse
ListCharactersFilter
ListCharactersFilter contains optional filters for listing characters.
| Field | Type | Label | Description |
|---|
| id | string | optional | Filter by character id |
ListCharactersRequest
ListCharactersRequest contains the user_id of the user.
ListCharactersResponse
ListCharactersResponse contains a list of characters for the user.
| Field | Type | Label | Description |
|---|
| characters | Character | repeated | |
ListCollectionsRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
ListCollectionsResponse
| Field | Type | Label | Description |
|---|
| collections | Collection | repeated | |
ListGenerationCatalogRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | User whose available generation catalog should be listed. |
ListGenerationCatalogResponse
| Field | Type | Label | Description |
|---|
| items | GenerationCatalogItem | repeated | Published workflow-backed generation modes, including unavailable entries so clients can render disabled choices with reasons. |
| Field | Type | Label | Description |
|---|
| search | string | optional | |
| media_type | MediaType | optional | |
| media_tag_id | string | repeated | |
| kitsune_only | bool | optional | If true, only return Kitsune media examples |
| welcome_only | bool | optional | If true, only return welcome examples and tags |
| nsfw_disabled | bool | optional | If true, exclude NSFW examples even if user has KYC |
| media_example_id | string | optional | If set, return only the example with this id |
| Field | Type | Label | Description |
|---|
| order | MediaOrder | | |
| date_from | string | | Half-open created_at range [date_from, date_to), RFC3339. Empty = no bound. |
| date_to | string | | |
| display_type | MediaDisplayType | | |
| text_search | string | | |
| media_type | MediaType | optional | |
| exclude_nsfw | bool | optional | exclude_nsfw drops 18+ rows from the result set. Applied in SQL so paging stays correct: a client that filtered the page it received would return short pages and eventually skip rows. Unset = no rating filter (legacy). |
ListMediaRequest contains the user_id, character_id, and optional page,
limit, and filter.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| media_ids | string | repeated | |
| media_statuses | MediaStatus | repeated | |
| page | int32 | | |
| limit | int32 | | |
| filter | ListMediaFilter | | |
| skip_total | bool | | skip_total opts out of the expensive COUNT(*) on the hot path. When set, the response omits total (left at 0) and relies on has_more for pagination. |
ListMediaResponse contains a list of available and pending media for the
character.
| Field | Type | Label | Description |
|---|
| media | Media | repeated | |
| total | int32 | | |
| has_more | bool | | has_more indicates whether more media exist beyond the current page. Always populated; preferred over total when skip_total is set on the request. |
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| media_type | MediaType | | A category is listed when it holds content of the type asked for, so this is what decides whether a video-only category appears at all. Exactly one of media_type or media_types must be set. |
| nsfw_disabled | bool | | |
| media_types | MediaType | repeated | For surfaces that offer several media types at once: a category is listed when it holds content of ANY of them. A dump takes photos, videos and carousels in one submit, so asking per type would hide each type’s categories from the other two. |
| Field | Type | Label | Description |
|---|
| tags | MediaTag | repeated | |
Media contains the details of a media.
| Field | Type | Label | Description |
|---|
| media_id | string | | |
| media_type | MediaType | | |
| media_created_at | string | | |
| media_image_url | string | | |
| media_video_url | string | | |
| media_thumbnail_url | string | | |
| media_video_preview_url | string | | |
| media_custom_text | string | optional | |
| media_estimated_wait_time | int32 | optional | |
| media_generation_started_at | string | optional | |
| media_status | MediaStatus | | |
| media_is_favorite | bool | | |
| media_is_archived | bool | | |
| media_feedback | string | optional | |
| media_example_id | string | optional | |
| media_source_id | string | optional | ID of the source media, if any |
| media_video_prompt | string | optional | Prompt for video generation |
| media_source_url | string | optional | URL of the source media, if any |
| media_is_eligible_for_free_edit | bool | | |
| media_aspect_ratio | AspectRatio | | |
| media_has_audio | bool | | If true, the media has audio |
| media_is_nsfw | bool | | Whether the media is NSFW |
| media_carousel_items | Media | repeated | If carousel, ordered items (first is main) |
| media_controls | MediaExampleControls | | |
| media_failure_reason | MediaFailureReason | | |
| media_character_id | string | optional | Character context for the cross-character gallery (ListAllMedia). The id is always set; name/foxy_handle are populated when the character relation is loaded (FOXY-372/360). |
| media_character_name | string | optional | |
| media_character_foxy_handle | string | optional | |
| media_workflow_name | string | optional | |
| media_source_is_input | bool | | True when this media’s source row is a hidden generation input upload (INTERNAL_INPUT scope) rather than a real gallery original. Lets clients tell “I was edited from that picture” apart from “I was generated using an upload the user never sees”, which otherwise look identical because both populate media_source_id and media_source_url. |
| media_family_key | string | optional | The generation-catalog family this media was dispatched through (faceted dispatch only). Recorded at create time so gallery re-use can reopen the same product surface even after the family’s member workflows change — deriving it from media_workflow_name breaks the moment a family swaps members. |
| Field | Type | Label | Description |
|---|
| media_example_id | string | | |
| media_example_type | string | | |
| media_type | MediaType | | |
| media_image_url | string | | |
| media_video_url | string | | |
| media_video_thumbnail_url | string | | |
| media_video_preview_url | string | | |
| media_custom_text | string | | |
| media_location | string | | |
| media_tags | string | repeated | |
| character_model_types | CharacterModelType | repeated | |
| media_aspect_ratio | AspectRatio | | |
| media_explicitness_level | MediaExplicitnessLevel | | |
| media_image_urls | string | repeated | |
| media_controls | MediaExampleControls | | |
| workflow_name | string | optional | |
| family_key | string | optional | |
| workflow_contract | string | optional | JSON: sirloin-derived MediaGenerationContract ({ inputs, outputs, compatibility }), same shape as GenerationCatalogItem.contract_json. |
| workflow_base_price | int32 | optional | Derived from the workflow pricing block. |
| source_variant | string | optional | JSON: source variant axis tuple (family-backed examples) |
| input_values | string | optional | JSON: workflow trigger inputs the example was generated with |
| input_overrides_by_workflow | string | optional | JSON: live config-driven flags per workflow the example can run as (own + family members): { [workflowName]: { [inputKey]: { visible, editable } } }. |
| Field | Type | Label | Description |
|---|
| duration | int32 | repeated | |
| price_base_multiplier | float | | |
| Field | Type | Label | Description |
|---|
| media_tag_id | string | | |
| media_tag_name | string | | |
| media_tag_image_url | string | | |
| media_tag_order | int32 | | |
| media_tag_is_welcome | bool | | |
| media_tag_parent_id | string | | Set when this category sits under another one. Explore lists parent-less tags as chips and a parent’s children as subcategory tiles inside it. |
| media_tag_explicitness_level | MediaExplicitnessLevel | | The category’s own rating, so consumers can tell an adult category from a general one directly. Without it the only way to know was to request the catalogue twice — once unfiltered, once SFW-only — and treat the difference as adult, which fails open: a category present in both lists reads as general and silently skips the age gate. |
| media_tag_has_own_content | bool | | True when examples are tagged on this category itself. A parent that only holds subcategories is false: it is listed as a shelf, but it is not a choice of its own next to the children it contains. |
| media_tag_is_video_only | bool | | True when this category is meant for video and holds nothing else. Set in fennec rather than inferred from current inventory, which would flip the moment one stray photo is tagged and says nothing about what the category is for. Surfaces offering more than one media type use it to label the category instead of hiding it. |
NudifyReferenceItem
NudifyReferenceResultItem
NudifyReferencesRequest
| Field | Type | Label | Description |
|---|
| items | NudifyReferenceItem | repeated | Exactly 3 items; sirloin handler enforces len(items) == 3. |
| bust_size | string | | |
| genitalia_style | string | | |
| user_id | string | | Set by brisket from the authenticated session. Sirloin verifies that every item path belongs to a character owned by this user before forwarding to brain so the eventual nudify-results output can’t be a nudification of someone else’s photo. |
NudifyReferencesResponse
PreviewContentDumpRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| tag_ids | string | repeated | The categories to draw from, required in both modes. A dice roll is expanded to every offered category by the client, so what a roll may draw from lives in one place rather than being duplicated here. |
Empty is rejected: it is a client that failed to resolve its categories, not an instruction to pick from everything. |
| image_count | int32 | | |
| video_count | int32 | | |
| carousel_count | int32 | | |
| nsfw | bool | | Which pool to draw from. Not the platform’s additive nsfw_disabled: 18+ here means NSFW only, and its absence means NSFW is excluded even for a user entitled to it, so a category dump never returns 18+ content. |
PreviewContentDumpResponse
| Field | Type | Label | Description |
|---|
| picks | ContentDumpPick | repeated | |
| total_cost | int32 | | |
| availability | ContentDumpAvailability | repeated | |
| used_tag_ids | string | repeated | Which of the requested categories actually produced a pick. A dump drawn from several packs can end up taking everything from one of them without saying so — the shortfall is reported per media type, and a pack that contributed nothing looks identical to one that contributed its share. |
PurchaseShopCharacterRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| reservation_token | string | | |
PurchaseShopCharacterResponse
| Field | Type | Label | Description |
|---|
| character_id | string | | |
| credits_charged | int32 | | |
ReleaseReservationRequest
| Field | Type | Label | Description |
|---|
| reservation_token | string | | |
| user_id | string | | |
ReleaseReservationResponse
RequestCharacterLikenessManualReviewImage
RequestCharacterLikenessManualReviewRequest
RequestCharacterLikenessManualReviewResponse
RequestCharacterLikenessManualReviewResult
RequestWelcomePicsRequest
RequestWelcomePicsResponse
| Field | Type | Label | Description |
|---|
| requested_count | int32 | | |
ReserveCharacterRequest
ReserveCharacterResponse
| Field | Type | Label | Description |
|---|
| reservation_token | string | | |
| expires_at | string | | RFC3339 |
ResetKYCVerificationRequest
ResetKYCVerificationRequest contains the user_id of the user to reset KYC for.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
ResetKYCVerificationResponse
ResetKYCVerificationResponse is returned when account KYC is reset.
SelectCharacterReferenceCandidateResponse
SelectCharacterReferenceCandidateResponse is returned when a character
reference candidate is selected.
ShopCharacter
ShopCharacter represents a virtual influencer in the shop catalogue.
StartKYCVerificationRequest
StartKYCVerificationRequest contains the user_id of the user to start KYC for.
StartKYCVerificationResponse
StartKYCVerificationResponse contains a verification URL and the verification
session ID from the KYC provider.
| Field | Type | Label | Description |
|---|
| verification_url | string | | |
| verification_id | string | | |
SubmitFeedbackRequest
SubmitFeedbackResponse
TriggerCharacterReferenceImageUploadedRequest
TriggerCharacterReferenceImageUploadedRequest contains the user_id and
character_id of the character to trigger processing of the uploaded reference
image.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| kyc_image_path | string | optional | Optional path to KYC image. Temporary until we fetch the image serverside. |
TriggerCharacterReferenceImageUploadedResponse
TriggerCharacterReferenceImageUploadedResponse is returned when the
processing of the uploaded reference image is triggered.
UpdateCharacterCustomViVerificationRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| character_instagram_handle | string | | |
| character_twitter_handle | string | | |
| another_social_profile | string | | |
| creation_source | string | | |
| custom_vi_evidence_paths | string | repeated | Full replacement of the character’s evidence paths array. Pass the canonical list the user ended the form with. |
UpdateCharacterCustomViVerificationResponse
UpdateCharacterReferenceDatasetImage
UpdateCharacterReferenceDatasetRequest carries updated dataset image metadata.
UpdateCharacterReferenceDatasetRequest
UpdateCharacterReferenceDatasetResponse
UpdateCharacterReferenceDatasetResponse is returned once dataset swap succeeds.
UpdateCharacterRequest
UpdateCharacterRequest contains the user_id, character_id, and updated
character details.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| character_name | string | optional | |
| character_instagram_handle | string | optional | |
| character_twitter_handle | string | optional | |
| gender | Gender | optional | |
| character_filter | CharacterImageFilter | optional | |
| character_hair_color | string | optional | |
| character_hair_length | string | optional | |
| character_hair_style | string | optional | |
| character_model_strictness | int32 | optional | |
| character_body_type | string | optional | |
| character_is_tattoos | bool | optional | |
| character_is_bbl | bool | optional | |
| character_is_flirty | bool | optional | |
| character_is_glasses | bool | optional | |
| character_feedback | string | optional | |
| character_is_verified | bool | optional | Bypasses verification. Non-Prod only. |
| selected_pack_id | string | optional | |
| selected_example_id | string | optional | |
| kyc_image_path | string | optional | Optional path to KYC image. Temporary until we fetch the image serverside. |
| character_foxy_handle | string | optional | |
UpdateCharacterResponse
UpdateCharacterResponse is returned when a character is updated.
UpdateCollectionRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| collection_id | string | | |
| name | string | optional | Only the provided fields are updated (partial update). |
| description | string | optional | |
| is_public | bool | optional | |
UpdateCollectionResponse
UpdateUserProfileRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| email | string | | |
| nsfw_enabled | bool | optional | |
| nsfw_age_confirmed | bool | optional | |
UpdateUserProfileResponse
UserProfile
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| email | string | | |
| nsfw_enabled | bool | | |
| nsfw_age_confirmed | bool | | True once the user has confirmed they are 18 or older. Stored per account so the confirmation is asked once, not per device or per session. |
| nsfw_age_verified | bool | | True when the account’s age is already established, either by that confirmation or by a completed identity check. Ask for confirmation only when this is false: a KYC-verified user has already proved their age with a government document, so prompting them again asks for less than they gave. This is the same rule the media serve path applies. |
VerifyCharacterReferenceDatasetImageRequest
VerifyCharacterReferenceDatasetImageRequest contains the user_id,
character_id, and path of the reference dataset image to verify.
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| character_id | string | | |
| path | string | | |
| include_all_checks | bool | optional | If true, all checks will be performed, otherwise only the basic |
VerifyCharacterReferenceDatasetImageResponse
VerifyCharacterReferenceDatasetImageResponse is returned when the reference
dataset image is verified.
| Field | Type | Label | Description |
|---|
| user_id | string | | User that must own both the uploaded input and the character. |
| character_id | string | | Character whose reference face the upload is compared against. |
| media_id | string | | Hidden media.media ID returned by CreateMediaInputUpload. The uploaded object must already exist in storage. |
| Field | Type | Label | Description |
|---|
| verdict | SelfLikenessVerdict | | Outcome of the comparison. |
| similarity | float | | Cosine similarity between the two faces, 0 when no comparison ran. Diagnostics only: the verdict already applies the threshold. |
| threshold | float | | Similarity threshold the verdict was computed against. Diagnostics only. |
| Field | Type | Label | Description |
|---|
| output_key | string | | Stable output key from the normalized workflow contract. |
| media_type | MediaType | | Generated media type; currently image or video. |
| storage_path | string | | Durable storage path for the generated media. |
| thumbnail_path | string | | Optional thumbnail storage path for future gallery previews. |
| metadata_json | string | | Optional JSON metadata copied into the child media controls field. |
AspectRatio
| Name | Number | Description |
|---|
| ASPECT_RATIO_4_5 | 0 | |
| ASPECT_RATIO_9_16 | 1 | |
| ASPECT_RATIO_16_9 | 2 | |
| ASPECT_RATIO_1_1 | 3 | |
| ASPECT_RATIO_4_3 | 4 | |
| ASPECT_RATIO_3_4 | 5 | |
CharacterDatasetImageFailureReason
| Name | Number | Description |
|---|
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_UNSPECIFIED | 0 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_RESOLUTION | 1 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_GRAYSCALE | 2 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_MORE_THAN_ONE_PERSON | 3 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_DETECTION_FAILED | 4 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_SUNGLASSES_ON_FACE | 5 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_SHARPNESS | 6 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_TOO_BRIGHT | 7 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_TOO_DARK | 8 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_VISIBLE_NIPPLES | 9 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_CROSSED_LIMBS | 10 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_IMAGE_ENCODING | 11 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_DUPLICATE | 12 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_HANDS_NEAR_FACE | 13 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_LYING_DOWN | 14 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_KNEELING | 15 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_PHONE_OVER_FACE | 16 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_TEXT_DENSITY | 17 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_QUALITY_NOISE | 18 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NOT_A_FULL_BODY_IMAGE | 19 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NO_FACE_DETECTED | 20 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_NOT_FRONTAL | 21 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_NOT_EYE_LEVEL | 22 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_NOT_NEUTRAL_EXPRESSION_OR_TEETH_VISIBLE | 23 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_NOT_CLEAR | 24 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_SUNGLASSES_NOT_ALLOWED | 25 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_BELOW_HEAD_TO_SHOULDER | 26 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NOT_A_PORTRAIT_IMAGE | 27 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_SMALL_RESOLUTION | 28 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NUDITY_DETECTED | 29 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_UNDERAGE_DETECTED | 30 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_TOO_SMALL | 31 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NOT_A_FRONTAL_POSE | 32 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NOT_ARMS_DOWN | 33 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_BELOW_HEAD_TO_BUST | 34 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_HIGH_OR_LOW_ANGLE_SELFIE | 35 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_AI_GENERATED_IMAGE | 36 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_SCREENGRAB | 37 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_BREASTS_NOT_REVEALED | 38 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_NUDITY_MISSING | 39 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_FACE_NOT_MATCHING_REFERENCE | 40 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_CELEBRITY_DETECTED | 41 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_ILLEGAL_CONTENT_DETECTED | 42 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_OFFENSIVE_CONTENT_DETECTED | 43 | |
| CHARACTER_DATASET_IMAGE_FAILURE_REASON_MODERATION_FLAGGED | 44 | |
CharacterDatasetImageStatus
| Name | Number | Description |
|---|
| CHARACTER_DATASET_IMAGE_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_DATASET_IMAGE_STATUS_REVIEW | 1 | |
| CHARACTER_DATASET_IMAGE_STATUS_SELECTED | 2 | |
| CHARACTER_DATASET_IMAGE_STATUS_SUPERSEDED | 3 | |
| CHARACTER_DATASET_IMAGE_STATUS_REJECTED | 4 | |
CharacterImageFilter
buf:lint:ignore ENUM_VALUE_PREFIX
| Name | Number | Description |
|---|
| CHARACTER_IMAGE_FITLER_UNSPECIFIED | 0 | |
| NATURAL | 1 | |
| FILTER | 2 | |
CharacterLikenessRejectionReason
| Name | Number | Description |
|---|
| CHARACTER_LIKENESS_REJECTION_REASON_UNSPECIFIED | 0 | |
| CHARACTER_LIKENESS_REJECTION_REASON_NEEDS_PROOF_OF_CREATION | 1 | |
| CHARACTER_LIKENESS_REJECTION_REASON_REAL_IMAGES_OF_SOMEONE_ELSE | 2 | |
| CHARACTER_LIKENESS_REJECTION_REASON_UNUSABLE_FOR_GENERATION | 3 | |
| CHARACTER_LIKENESS_REJECTION_REASON_OTHER | 4 | |
CharacterModelType
| Name | Number | Description |
|---|
| CHARACTER_MODEL_TYPE_UNSPECIFIED | 0 | |
| CHARACTER_MODEL_TYPE_GFY | 1 | Go F Yourself character |
| CHARACTER_MODEL_TYPE_KITSUNE | 2 | Kitsune character |
CharacterStatus
| Name | Number | Description |
|---|
| CHARACTER_STATUS_UNSPECIFIED | 0 | |
| CHARACTER_STATUS_PENDING | 1 | |
| CHARACTER_STATUS_TRAINING | 2 | |
| CHARACTER_STATUS_AVAILABLE | 3 | |
| CHARACTER_STATUS_FAILED | 4 | |
CharacterType
| Name | Number | Description |
|---|
| CHARACTER_TYPE_UNSPECIFIED | 0 | |
| CHARACTER_TYPE_REAL | 1 | |
| CHARACTER_TYPE_VIRTUAL | 2 | |
Gender
buf:lint:ignore ENUM_VALUE_PREFIX
| Name | Number | Description |
|---|
| GENDER_UNSPECIFIED | 0 | |
| FEMALE | 1 | |
| MALE | 2 | |
GenerationCatalogAxisControlKind
GenerationCatalogAxisControlKind tells clients how to render an axis.
| Name | Number | Description |
|---|
| GENERATION_CATALOG_AXIS_CONTROL_KIND_UNSPECIFIED | 0 | |
| GENERATION_CATALOG_AXIS_CONTROL_KIND_DROPDOWN | 1 | |
| GENERATION_CATALOG_AXIS_CONTROL_KIND_TOGGLE | 2 | |
GenerationCatalogContractFieldType
GenerationCatalogContractFieldType is the proto-owned vocabulary for
generic workflow-backed generation inputs and outputs rendered by clients.
Contract JSON stores these enum value names so unknown or mistyped kinds do
not silently become app-specific string literals.
| Name | Number | Description |
|---|
| GENERATION_CATALOG_CONTRACT_FIELD_TYPE_UNSPECIFIED | 0 | |
| GENERATION_CATALOG_CONTRACT_FIELD_TYPE_TEXT | 1 | |
| GENERATION_CATALOG_CONTRACT_FIELD_TYPE_IMAGE_ARRAY | 2 | |
| GENERATION_CATALOG_CONTRACT_FIELD_TYPE_VIDEO_ARRAY | 3 | |
| GENERATION_CATALOG_CONTRACT_FIELD_TYPE_CHARACTER_ID_ARRAY | 4 | |
GenerationSurface
GenerationSurface identifies the product surface behind a generation. Absent
means an ordinary create flow, which is why there is an explicit unspecified
member.
Named “surface” rather than “source” because a media row already has two
unrelated sources: source_id, the parent row an edit derives from, and
source_variant, its faceted axis tuple.
| Name | Number | Description |
|---|
| GENERATION_SURFACE_UNSPECIFIED | 0 | |
| GENERATION_SURFACE_CONTENT_DUMP | 1 | |
KycVerificationPurpose
| Name | Number | Description |
|---|
| KYC_VERIFICATION_PURPOSE_UNSPECIFIED | 0 | |
| KYC_VERIFICATION_PURPOSE_NSFW_ONBOARDING | 1 | |
| KYC_VERIFICATION_PURPOSE_CELEBRITY_DETECTED | 2 | |
buf:lint:ignore ENUM_VALUE_PREFIX
| Name | Number | Description |
|---|
| MEDIA_DISPLAY_TYPE_UNSPECIFIED | 0 | |
| DEFAULT | 1 | |
| FAVORITES_ONLY | 2 | |
| ARCHIVE_ONLY | 3 | |
| Name | Number | Description |
|---|
| MEDIA_EXPLICITNESS_LEVEL_UNSPECIFIED | 0 | |
| MEDIA_EXPLICITNESS_LEVEL_SFW | 1 | |
| MEDIA_EXPLICITNESS_LEVEL_NSFW | 2 | |
| MEDIA_EXPLICITNESS_LEVEL_EXPLICIT | 3 | |
| MEDIA_EXPLICITNESS_LEVEL_SSFW | 4 | |
| Name | Number | Description |
|---|
| MEDIA_FAILURE_REASON_UNSPECIFIED | 0 | |
| MEDIA_FAILURE_REASON_UNDERAGE_DETECTED | 1 | |
| MEDIA_FAILURE_REASON_CELEBRITY_DETECTED | 2 | |
| MEDIA_FAILURE_REASON_NUDITY_DETECTED | 3 | |
| MEDIA_FAILURE_REASON_ILLEGAL_CONTENT_DETECTED | 4 | |
| MEDIA_FAILURE_REASON_OFFENSIVE_CONTENT_DETECTED | 5 | |
| MEDIA_FAILURE_REASON_MODERATION_FLAGGED | 6 | |
| Name | Number | Description |
|---|
| MEDIA_ORDER_UNSPECIFIED | 0 | |
| MEDIA_ORDER_NEWEST | 1 | |
| MEDIA_ORDER_OLDEST | 2 | |
| Name | Number | Description |
|---|
| MEDIA_STATUS_UNSPECIFIED | 0 | |
| MEDIA_STATUS_AVAILABLE | 1 | |
| MEDIA_STATUS_PENDING | 2 | |
| MEDIA_STATUS_GENERATING | 3 | |
| MEDIA_STATUS_FAILED | 4 | |
| Name | Number | Description |
|---|
| MEDIA_TYPE_UNSPECIFIED | 0 | |
| MEDIA_TYPE_IMAGE | 1 | |
| MEDIA_TYPE_VIDEO | 2 | |
| MEDIA_TYPE_CAROUSEL | 3 | |
SelfLikenessVerdict
SelfLikenessVerdict is the outcome of comparing an uploaded workflow input
against a character’s reference face. Only MISMATCH denies the edit; every
other non-match value means the check could not conclude, so the client must
never present it as “this is not you”.
| Name | Number | Description |
|---|
| SELF_LIKENESS_VERDICT_UNSPECIFIED | 0 | |
| SELF_LIKENESS_VERDICT_MATCH | 1 | Both faces were read and they are the same person. Unlock the form. |
| SELF_LIKENESS_VERDICT_MISMATCH | 2 | Both faces were read and they are different people. Expected result, not an error: deny the edit with a clear message and charge nothing. |
| SELF_LIKENESS_VERDICT_NO_FACE_DETECTED | 3 | No usable face was found in the uploaded image. Ask for a clearer photo. |
| SELF_LIKENESS_VERDICT_UNAVAILABLE | 4 | The check could not run: the face model was unavailable, Brain errored, or the character has no usable reference face. Retryable, never a denial. |
ShopCharacterAvailabilityStatus
| Name | Number | Description |
|---|
| SHOP_CHARACTER_AVAILABILITY_STATUS_UNSPECIFIED | 0 | |
| SHOP_CHARACTER_AVAILABILITY_STATUS_AVAILABLE | 1 | |
| SHOP_CHARACTER_AVAILABILITY_STATUS_RESERVED | 2 | |
| SHOP_CHARACTER_AVAILABILITY_STATUS_SOLD | 3 | |
ShopCharacterSortBy
| Name | Number | Description |
|---|
| SHOP_CHARACTER_SORT_BY_UNSPECIFIED | 0 | |
| SHOP_CHARACTER_SORT_BY_PRICE_TIER | 1 | |
| SHOP_CHARACTER_SORT_BY_CREATED_AT | 2 | |
| SHOP_CHARACTER_SORT_BY_NAME | 3 | |
ShopSortDirection
| Name | Number | Description |
|---|
| SHOP_SORT_DIRECTION_UNSPECIFIED | 0 | |
| SHOP_SORT_DIRECTION_ASC | 1 | |
| SHOP_SORT_DIRECTION_DESC | 2 | |
| Name | Number | Description |
|---|
| WORKFLOW_MEDIA_COMPLETION_STATUS_UNSPECIFIED | 0 | |
| WORKFLOW_MEDIA_COMPLETION_STATUS_SUCCEEDED | 1 | |
| WORKFLOW_MEDIA_COMPLETION_STATUS_FAILED | 2 | |
SirloinService
Sirloin Service
The service is used for internal communication within the Sirloin service.
Character management
The caller sends example ids and nothing else: Sirloin loads each example, resolves the workflow from the stored row, and uses that row’s own input values as the trigger. Clients therefore never assemble — or are trusted for — a dispatch payload, and the per-example round trips happen here rather than one HTTP request per item.
A failing example never fails the batch. Each item reports its own outcome in request order, so callers can retry only what did not start. |
| PreviewContentDump | PreviewContentDumpRequest | PreviewContentDumpResponse | PreviewContentDump picks the examples a content dump would run and prices them. Read-only: nothing is charged, enqueued or written, so a client may call it on every settings change.
Each example carries its own price, so a total cannot be derived from the requested counts alone — it exists only once the picks are known. The same pricing path charges at dispatch, so the quote and the bill agree. |
| ListGenerationCatalog | ListGenerationCatalogRequest | ListGenerationCatalogResponse | ListGenerationCatalog returns published workflow-backed generation modes that Sirloin can expose to app clients, including pricing, compatibility, and normalized input/output contracts. |
| CreateMediaInputUpload | CreateMediaInputUploadRequest | CreateMediaInputUploadResponse | CreateMediaInputUpload creates a hidden durable media record and presigned upload URL for workflow input files before the visible generation request is submitted. The hidden row remains pending-upload until GenerateMedia confirms the object exists in storage. |
| VerifyMediaInputSelfLikeness | VerifyMediaInputSelfLikenessRequest | VerifyMediaInputSelfLikenessResponse | VerifyMediaInputSelfLikeness compares an uploaded workflow input image against the character’s own frontal reference face. Users may only edit photos of themselves, so clients call this after the upload PUT succeeds and before unlocking the edit form. Read-only and free: no credits are spent, no generation is dispatched, and no rows are written.
This is face matching only. Protected-set moderation (CSAM, celebrity, illegal content) stays in the workflow and is not covered here. |
| CompleteWorkflowMedia | CompleteWorkflowMediaRequest | CompleteWorkflowMediaResponse | CompleteWorkflowMedia was the internal engine-to-Sirloin completion callback for the retired legacy workflow engine. The server no longer implements it (returns Unimplemented); the RPC is retained for wire compatibility only. |
| ListMedia | ListMediaRequest | ListMediaResponse | ListMedia returns a list of available and pending media for the character. |
| ListAllMedia | ListAllMediaRequest | ListMediaResponse | ListAllMedia returns a list of the user’s media across ALL of their characters (no character scope). Same filters/pagination as ListMedia. |
| ToggleMediaFavorite | ToggleMediaFavoriteRequest | ToggleMediaFavoriteResponse | ToggleMediaFavorite toggles the favorite status of a media item. |
| ToggleMediaArchived | ToggleMediaArchivedRequest | ToggleMediaArchivedResponse | ToggleMediaArchived toggles the archive status of a media item. |
| SubmitFeedback | SubmitFeedbackRequest | SubmitFeedbackResponse | SubmitFeedback submits feedback for the media item. |
| SetMediaDownloaded | SetMediaDownloadedRequest | SetMediaDownloadedResponse | SetMediaDownloaded toggles the downloaded status of a media item. |
| NudifyReferences | NudifyReferencesRequest | NudifyReferencesResponse | NudifyReferences nudifies a fixed batch of exactly 3 reference images. Proxies to brain via HTTP; sirloin owns the camelCase ↔ snake_case translation to brain. |
| ListMediaExamples | ListMediaExamplesRequest | ListMediaExamplesResponse | Lists MediaExamples returns a list of available media examples. |
| ListMediaTags | ListMediaTagsRequest | ListMediaTagsResponse | ListMediaTags returns a list of tags for a given media type. |
| RequestWelcomePics | RequestWelcomePicsRequest | RequestWelcomePicsResponse | RequestWelcomePics requests a batch of welcome pics for a character. |
| GetUserProfile | GetUserProfileRequest | GetUserProfileResponse | GetUserProfile returns the user’s profile settings. |
| UpdateUserProfile | UpdateUserProfileRequest | UpdateUserProfileResponse | UpdateUserProfile creates or updates the user’s profile settings.
Shop VI -------------------- |
| ListAvailableCharacters | ListAvailableCharactersRequest | ListAvailableCharactersResponse | ListAvailableCharacters returns a paginated catalogue of virtual influencers available for purchase, with attribute filters and sorting. |
| GetShopCharacter | GetShopCharacterRequest | GetShopCharacterResponse | GetShopCharacter returns full details of a single shop VI including attributes, catalogue media, and price. |
| ReserveCharacter | ReserveCharacterRequest | ReserveCharacterResponse | ReserveCharacter acquires a time-limited purchase lock on a VI. Returns ALREADY_EXISTS if the character is already reserved. |
| PurchaseShopCharacter | PurchaseShopCharacterRequest | PurchaseShopCharacterResponse | PurchaseShopCharacter purchases a reserved shop VI character using credits. The reservation must be valid and the user must have sufficient credits. |
| ReleaseReservation | ReleaseReservationRequest | ReleaseReservationResponse | ReleaseReservation releases an expired or cancelled reservation. |
| CreateCollection | CreateCollectionRequest | CreateCollectionResponse | CreateCollection creates a new (empty) media collection for the user. |
| UpdateCollection | UpdateCollectionRequest | UpdateCollectionResponse | UpdateCollection updates a collection’s name/description/visibility. |
| DeleteCollection | DeleteCollectionRequest | DeleteCollectionResponse | DeleteCollection deletes a collection (membership rows are removed too; the underlying media is untouched). |
| ListCollections | ListCollectionsRequest | ListCollectionsResponse | ListCollections returns the user’s collections with item counts and a cover preview. |
| AddMediaToCollection | AddMediaToCollectionRequest | AddMediaToCollectionResponse | AddMediaToCollection adds one or more media items to a collection (idempotent — re-adding an existing item is a no-op). |
| RemoveMediaFromCollection | RemoveMediaFromCollectionRequest | RemoveMediaFromCollectionResponse | RemoveMediaFromCollection removes one or more media items from a collection (the media itself is not deleted). |
Top
sirloin/v5/strip.proto
GrowthDataPoint
| Field | Type | Label | Description |
|---|
| date | string | | Date in format “YYYY-MM-DD” |
| count | int32 | | Count for that date |
StripAuditLog
StripBypassCharacterOnboardingChecksRequest
StripBypassCharacterOnboardingChecksResponse
| Field | Type | Label | Description |
|---|
| bypass_onboarding_checks_until | string | | |
StripBypassUserKYCRequest
StripBypassUserKYCResponse
| Field | Type | Label | Description |
|---|
| ondato_verification_id | string | | |
| kyc_status | string | | |
StripCharacter
StripCharacterDatasetImage
StripCreateCharacterRequest
StripCreateCharacterResponse
StripCreateClerkUserRequest
| Field | Type | Label | Description |
|---|
| email | string | | |
| role | string | | Optional: assign role immediately after creation |
| admin_user_id | string | | |
| admin_user_email | string | | |
StripCreateClerkUserResponse
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| email | string | | |
| already_existed | bool | | true when an existing Clerk user was reused instead of creating a duplicate |
StripDatasetImageWithCharacter
StripDeleteCharacterRequest
StripDeleteCharacterResponse
StripDeleteClerkUserRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | Clerk user id to delete |
| admin_user_id | string | | |
| admin_user_email | string | | |
StripDeleteClerkUserResponse
StripDeleteFilterPresetRequest
StripDeleteFilterPresetResponse
| Field | Type | Label | Description |
|---|
| deleted | bool | | |
StripDeleteUserRoleRequest
StripDeleteUserRoleResponse
StripFilterPreset
Saved filter preset messages
StripFoxy360Artifact
StripFoxy360CreateThreadRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
StripFoxy360CreateThreadResponse
StripFoxy360GetRunRequest
| Field | Type | Label | Description |
|---|
| run_id | string | | |
StripFoxy360GetRunResponse
StripFoxy360ListArtifactsRequest
StripFoxy360ListArtifactsResponse
StripFoxy360ListMessagesRequest
StripFoxy360ListMessagesResponse
StripFoxy360Message
StripFoxy360Run
StripFoxy360SendMessageRequest
StripFoxy360SendMessageResponse
StripFoxy360Thread
StripGetAuditLogRequest
| Field | Type | Label | Description |
|---|
| audit_log_id | string | | |
StripGetAuditLogResponse
StripGetDashboardStatsRequest
Dashboard statistics messages
| Field | Type | Label | Description |
|---|
| growth_days | int32 | | Number of days to include in growth data |
| top_admins_limit | int32 | | Number of top admins to return |
StripGetDashboardStatsResponse
StripGetSchemaRequest
StripGetSchemaResponse
StripGetUserRoleRequest
| Field | Type | Label | Description |
|---|
| user_id | string | | |
StripGetUserRoleResponse
| Field | Type | Label | Description |
|---|
| role | string | | Empty if no role assigned |
StripLikenessEvidenceFile
StripLikenessHistoryCharacter
StripLikenessHistoryEvent
| Field | Type | Label | Description |
|---|
| action | string | | UPLOADED / APPROVED / REJECTED / SUPERSEDED |
| from_status | string | | |
| to_status | string | | |
| reviewer_email | string | | |
| occurred_at | string | | RFC3339 |
| reason | string | | raw rejection reason enum code, empty unless REJECTED |
| reason_note | string | | optional free-text note captured at rejection |
StripLikenessHistorySlot
| Field | Type | Label | Description |
|---|
| slot_token | string | | face_frontal, full_body, *_nsfw, empty if unrecognized |
| current_status | string | | SELECTED / REJECTED / SUPERSEDED |
| image_url | string | | |
| events | StripLikenessHistoryEvent | repeated | chronological, oldest first |
StripLikenessRejectionReasonOption
StripLikenessReviewItem
StripListAuditLogsRequest
StripListAuditLogsResponse
StripListAvailableCharactersRequest
StripListAvailableCharactersResponse
StripListCharactersRequest
CHARACTER_STATUS_AVAILABLE, CHARACTER_STATUS_ACTIVE, etc. |
| gender_filter | string | | CHARACTER_MALE, CHARACTER_FEMALE, CHARACTER_OTHER |
| model_type_filter | string | | CHARACTER_MODEL_TYPE_REALISTIC, CHARACTER_MODEL_TYPE_ANIME, etc. |
| created_from | string | | Date filter (YYYY-MM-DD format) |
| created_to | string | | Date filter (YYYY-MM-DD format) |
| updated_from | string | | Date filter (YYYY-MM-DD format) |
| updated_to | string | | Date filter (YYYY-MM-DD format) |
| has_media | bool | | Activity filter
Filter by characters that have media |
| filter_has_media | bool | | Whether to apply has_media filter |
| user_id | string | | Filter by user ID |
| character_type_filter | string | | CHARACTER_TYPE_REAL, CHARACTER_TYPE_VIRTUAL |
StripListCharactersResponse
StripListDatasetImagesRequest
CHARACTER_STATUS_AVAILABLE, CHARACTER_STATUS_ACTIVE, etc. |
| gender_filter | string | | CHARACTER_MALE, CHARACTER_FEMALE, CHARACTER_OTHER |
| model_type_filter | string | | CHARACTER_MODEL_TYPE_REALISTIC, CHARACTER_MODEL_TYPE_ANIME, etc. |
| created_from | string | | Date filter (YYYY-MM-DD format) - image created date |
| created_to | string | | Date filter (YYYY-MM-DD format) - image created date |
StripListDatasetImagesResponse
StripListFilterPresetsRequest
StripListFilterPresetsResponse
StripListLikenessHistoryRequest
| Field | Type | Label | Description |
|---|
| cursor | string | | |
| limit | int32 | | |
| search | string | | Search by character name, user email, character ID |
StripListLikenessHistoryResponse
StripListLikenessReviewsRequest
| Field | Type | Label | Description |
|---|
| cursor | string | | |
| limit | int32 | | |
| search | string | | Search by character name, user email, character ID |
StripListLikenessReviewsResponse
MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO |
| status_filter | string | | MEDIA_STATUS_AVAILABLE, MEDIA_STATUS_PENDING, etc. |
| created_from | string | | Date filter (YYYY-MM-DD format) |
| created_to | string | | Date filter (YYYY-MM-DD format) |
| generation_mode_filter | string | | “edit”, “signature”, “basic”, “custom_text” |
StripListPopularCategoriesRequest
Popular categories (tags) with usage statistics
| Field | Type | Label | Description |
|---|
| created_from | string | | Time range filters for media.created_at |
Date filter (YYYY-MM-DD format) |
| created_to | string | | Date filter (YYYY-MM-DD format) |
| usage_type | StripPopularUsageType | | Usage type filter
Filter by usage type (welcome vs normal) |
| limit | int32 | | Limit the number of categories returned
Default 20 |
| explicitness_level | string | | Explicitness level filter
Filter by explicitness level (e.g., “MEDIA_EXPLICITNESS_LEVEL_SFW”) |
| media_type_filter | string | | Media type filter
IMAGE, VIDEO, or CAROUSEL |
StripListPopularCategoriesResponse
StripListPopularExamplesRequest
Date filter (YYYY-MM-DD format) |
| created_to | string | | Date filter (YYYY-MM-DD format) |
| tag_id | string | | Tag/category filter
Filter examples by tag/category ID |
| usage_type | StripPopularUsageType | | Usage type filter
Filter by usage type (welcome vs normal) |
| explicitness_level | string | | Explicitness level filter
Filter by explicitness level (e.g., “MEDIA_EXPLICITNESS_LEVEL_SFW”) |
| media_type_filter | string | | Media type filter
IMAGE, VIDEO, or CAROUSEL |
StripListPopularExamplesResponse
StripListUserRolesRequest
StripListUserRolesResponse
StripListUsersRequest
StripListUsersResponse
| Field | Type | Label | Description |
|---|
| users | StripUser | repeated | |
StripLogAuditRequest
StripLogAuditResponse
| Field | Type | Label | Description |
|---|
| audit_log_id | string | | |
StripPopularCategory
| Field | Type | Label | Description |
|---|
| id | string | | |
| name | string | | |
| image_url | string | | |
| usage_count | int32 | | Total usage count for examples in this category |
| example_count | int32 | | Number of examples in this category |
StripPopularExample
StripResolveLikenessReviewRequest
StripResolveLikenessReviewResponse
StripRunReadonlyQueryRequest
StripRunReadonlyQueryResponse
StripSaveFilterPresetRequest
StripSchemaColumn
StripSchemaTable
StripSetUserRoleRequest
StripSetUserRoleResponse
StripShopCharacter
StripSyncUserOndatoVerificationRequest
StripSyncUserOndatoVerificationResponse
StripUpdateCharacterRequest
StripUpdateCharacterResponse
StripUpdateUserProcessorsRequest
StripUpdateUserProcessorsResponse
StripUpdateUserRequest
StripUpdateUserResponse
StripUser
StripUserRole
TopUserActivity
| Field | Type | Label | Description |
|---|
| user_id | string | | |
| email | string | | |
| media_count | int32 | | |
| top_tags | string | repeated | Top 3 favorite categories/tags |
SortDirection
| Name | Number | Description |
|---|
| SORT_DIRECTION_UNSPECIFIED | 0 | |
| SORT_DIRECTION_ASC | 1 | |
| SORT_DIRECTION_DESC | 2 | |
StripLikenessRejectionReason
| Name | Number | Description |
|---|
| STRIP_LIKENESS_REJECTION_REASON_UNSPECIFIED | 0 | |
| STRIP_LIKENESS_REJECTION_REASON_NEEDS_PROOF_OF_CREATION | 1 | |
| STRIP_LIKENESS_REJECTION_REASON_REAL_IMAGES_OF_SOMEONE_ELSE | 2 | |
| STRIP_LIKENESS_REJECTION_REASON_UNUSABLE_FOR_GENERATION | 3 | |
| STRIP_LIKENESS_REJECTION_REASON_OTHER | 4 | |
StripLikenessReviewResolution
| Name | Number | Description |
|---|
| STRIP_LIKENESS_REVIEW_RESOLUTION_UNSPECIFIED | 0 | |
| STRIP_LIKENESS_REVIEW_RESOLUTION_APPROVED | 1 | |
| STRIP_LIKENESS_REVIEW_RESOLUTION_REJECTED | 2 | |
StripListAuditLogsSortBy
| Name | Number | Description |
|---|
| LIST_AUDIT_LOGS_SORT_BY_UNSPECIFIED | 0 | |
| LIST_AUDIT_LOGS_SORT_BY_CREATED_AT | 1 | |
| LIST_AUDIT_LOGS_SORT_BY_USER_ID | 2 | |
| LIST_AUDIT_LOGS_SORT_BY_ACTION | 3 | |
| LIST_AUDIT_LOGS_SORT_BY_ENTITY_TYPE | 4 | |
| Name | Number | Description |
|---|
| LIST_CHARACTERS_SORT_BY_UNSPECIFIED | 0 | |
| LIST_CHARACTERS_SORT_BY_CREATED_AT | 1 | |
| LIST_CHARACTERS_SORT_BY_UPDATED_AT | 2 | |
| LIST_CHARACTERS_SORT_BY_DELETED_AT | 3 | |
| LIST_CHARACTERS_SORT_BY_NAME | 4 | |
| LIST_CHARACTERS_SORT_BY_GENDER | 5 | |
| LIST_CHARACTERS_SORT_BY_MODEL_TYPE | 6 | |
| LIST_CHARACTERS_SORT_BY_INSTAGRAM_HANDLE | 7 | |
| LIST_CHARACTERS_SORT_BY_TWITTER_HANDLE | 8 | |
| LIST_CHARACTERS_SORT_BY_STATUS | 9 | |
| LIST_CHARACTERS_SORT_BY_REFERENCE_IMAGE_URL | 10 | |
| LIST_CHARACTERS_SORT_BY_REFERENCE_IMAGE_AGE | 11 | |
| LIST_CHARACTERS_SORT_BY_ETHNICITY | 12 | |
| LIST_CHARACTERS_SORT_BY_HAIR_COLOR | 13 | |
| LIST_CHARACTERS_SORT_BY_HAIR_STYLE | 14 | |
| LIST_CHARACTERS_SORT_BY_HAIR_LENGTH | 15 | |
StripListDatasetImagesSortBy
Dataset images listing (direct query, not through characters)
| Name | Number | Description |
|---|
| LIST_DATASET_IMAGES_SORT_BY_UNSPECIFIED | 0 | |
| LIST_DATASET_IMAGES_SORT_BY_CREATED_AT | 1 | |
| LIST_DATASET_IMAGES_SORT_BY_CHARACTER_NAME | 2 | |
| Name | Number | Description |
|---|
| LIST_MEDIA_SORT_BY_UNSPECIFIED | 0 | |
| LIST_MEDIA_SORT_BY_CREATED_AT | 1 | |
| LIST_MEDIA_SORT_BY_DELETED_AT | 2 | |
| LIST_MEDIA_SORT_BY_STATUS | 3 | |
| LIST_MEDIA_SORT_BY_TYPE | 4 | |
| LIST_MEDIA_SORT_BY_USER_EMAIL | 5 | |
| LIST_MEDIA_SORT_BY_CHARACTER_NAME | 6 | |
StripListPopularExamplesSortBy
| Name | Number | Description |
|---|
| LIST_POPULAR_EXAMPLES_SORT_BY_UNSPECIFIED | 0 | |
| LIST_POPULAR_EXAMPLES_SORT_BY_USAGE_COUNT | 1 | |
| LIST_POPULAR_EXAMPLES_SORT_BY_CREATED_AT | 2 | |
| Name | Number | Description |
|---|
| LIST_USERS_SORT_BY_UNSPECIFIED | 0 | |
| LIST_USERS_SORT_BY_CREATED_AT | 1 | |
| LIST_USERS_SORT_BY_UPDATED_AT | 2 | |
| LIST_USERS_SORT_BY_CANCELLED_AT | 3 | |
| LIST_USERS_SORT_BY_REFERRAL_CODE | 4 | |
StripPopularUsageType
| Name | Number | Description |
|---|
| POPULAR_USAGE_TYPE_UNSPECIFIED | 0 | All usage |
| POPULAR_USAGE_TYPE_WELCOME | 1 | cost = 0 |
| POPULAR_USAGE_TYPE_NORMAL | 2 | cost > 0, excluding content-dump rows |
UserStatusFilter
| Name | Number | Description |
|---|
| USER_STATUS_FILTER_UNSPECIFIED | 0 | |
| USER_STATUS_FILTER_ALL | 1 | |
| USER_STATUS_FILTER_ACTIVE | 2 | |
| USER_STATUS_FILTER_INACTIVE | 3 | |
| USER_STATUS_FILTER_CANCELLED | 4 | |
StripService
Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|---|
| double | | double | double | float | float64 | double | float | Float |
| float | | float | float | float | float32 | float | float | Float |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |