Table of Contents
Top
angzarr/cloudevents.proto
CloudEvent
docs:start:cloud_event
CloudEvent represents a single event for external consumption.
Client projectors create these by filtering/transforming internal events.
Framework fills envelope fields (id, source, time) from Cover/EventPage
if not explicitly set by the client.
The data field is a protobuf Any that framework converts to JSON via
prost-reflect using the descriptor pool. Clients should pack a "public"
proto message that omits sensitive fields.
| Field | Type | Label | Description |
|---|
| type | string | | Event type (e.g., "com.example.order.created"). Default: proto type_url suffix from original event. |
| data | google.protobuf.Any | | Event payload as proto Any. Framework converts to JSON for CloudEvents output. Client should filter sensitive fields before packing. |
| extensions | CloudEvent.ExtensionsEntry | repeated | Custom extension attributes. Keys should follow CloudEvents naming (lowercase, no dots). Framework adds correlationid automatically if present in Cover. |
| id | string | optional | Optional overrides. Framework uses Cover/EventPage values if not set. |
Default: {domain}:{root_id}:{sequence} |
| source | string | optional | Default: angzarr/{domain} |
| subject | string | optional | Default: aggregate root ID |
CloudEvent.ExtensionsEntry
| Field | Type | Label | Description |
|---|
| key | string | | |
| value | string | | |
CloudEventsResponse
CloudEventsResponse is returned by client projectors in Projection.projection.
Framework detects this type by checking projection.type_url and routes
the events to configured sinks (HTTP webhook, Kafka).
Client may return 0 events (skip), 1 event (typical), or N events
(fan-out scenarios like multi-tenant notifications).
Top
angzarr/command_handler.proto
BusinessResponse
Wrapper response for BusinessLogic.Handle
| Field | Type | Label | Description |
|---|
| events | EventBook | | Business provides compensation events |
| revocation | RevocationResponse | | Business requests framework action |
| notification | Notification | | Forward rejection notification upstream |
CommandResponse
Response from entity - aggregate events + sync projector results
| Field | Type | Label | Description |
|---|
| events | EventBook | | Events from the target aggregate |
| projections | Projection | repeated | Synchronous projector results |
FactInjectionResponse
docs:start:fact_injection
Response from fact injection.
Indicates whether facts were newly persisted or already existed (idempotent).
Request uses EventRequest with:
- events: EventBook containing fact events (with FactSequence markers)
- sync_mode: Controls sync processing (default: async)
- route_to_handler: Whether to invoke command handler's handle_fact (default: true)
IMPORTANT: Set Cover.external_id for idempotency. The coordinator uses this
to deduplicate fact injections - subsequent requests with the same external_id
return the original events without re-persisting.
| Field | Type | Label | Description |
|---|
| events | EventBook | | Persisted events with real sequence numbers |
| already_processed | bool | | True if external_id was already seen (idempotent response) |
| projections | Projection | repeated | Synchronous projector results (if any) |
ReplayRequest
Request to replay events and compute resulting state
| Field | Type | Label | Description |
|---|
| base_snapshot | Snapshot | | Starting state (empty = initial state) |
| events | EventPage | repeated | Events to apply in order |
ReplayResponse
Response with computed state after replay
RevocationResponse
client logic requests framework to handle revocation
| Field | Type | Label | Description |
|---|
| emit_system_revocation | bool | | Emit SagaCompensationFailed event |
| send_to_dead_letter_queue | bool | | Send to DLQ |
| escalate | bool | | Flag for alerting/human intervention |
| abort | bool | | Stop saga chain, propagate error to caller |
| reason | string | | Context/reason |
SpeculateCommandHandlerRequest
Request for speculative command execution against temporal state.
CommandHandlerCoordinatorService
CommandHandlerCoordinatorService: orchestrates command processing for domain aggregates
| Method Name | Request Type | Response Type | Description |
|---|
| HandleCommand | CommandRequest | CommandResponse | Process command with optional sync mode (default: async fire-and-forget) |
| HandleEvent | EventRequest | FactInjectionResponse | Inject fact events - external realities that cannot be rejected. Idempotent: subsequent requests with same external_id return original events. Use EventRequest.route_to_handler to control command handler invocation. |
| HandleSyncSpeculative | SpeculateCommandHandlerRequest | CommandResponse | Speculative execution - execute against temporal state without persisting |
| HandleCompensation | CommandRequest | BusinessResponse | Compensation flow - returns BusinessResponse for saga compensation handling. If business returns events, persists them. Caller handles revocation flags. |
CommandHandlerService
CommandHandlerService: client logic that processes commands and emits events
Business logic layer that implements command handling for a domain aggregate
client logic doesn't care about sync - coordinator decides
| Method Name | Request Type | Response Type | Description |
|---|
| Handle | ContextualCommand | BusinessResponse | Process command and return business response (events or revocation request) |
| Replay | ReplayRequest | ReplayResponse | Replay events to compute state (for conflict detection) Optional: only needed if aggregate supports MERGE_COMMUTATIVE |
Top
DeleteEditionEvents
Delete all events for an edition+domain combination.
Main timeline ('angzarr' or empty edition name) cannot be deleted.
| Field | Type | Label | Description |
|---|
| edition | string | | Edition name to delete from |
| domain | string | | Domain to delete from |
EditionEventsDeleted
Response from edition event deletion.
| Field | Type | Label | Description |
|---|
| edition | string | | |
| domain | string | | |
| deleted_count | uint32 | | |
| deleted_at | string | | |
Top
angzarr/process_manager.proto
ProcessManagerHandleRequest
Phase 2 request: full context for PM decision.
| Field | Type | Label | Description |
|---|
| trigger | EventBook | | Full state of triggering domain. |
| process_state | EventBook | | Current process manager state (event-sourced). |
| destinations | EventBook | repeated | Additional destinations fetched per Prepare response. |
ProcessManagerHandleResponse
Phase 2 response: local events, then remote commands and facts.
Execution order: process_events persisted first, then commands sent, then facts injected.
| Field | Type | Label | Description |
|---|
| process_events | EventBook | | Local: Events for the process manager's own domain (non-duplicative workflow state). These are persisted via AggregateCoordinator to the PM's domain. |
| commands | CommandBook | repeated | Remote: Commands to issue to other aggregates. |
| facts | EventBook | repeated | Remote: Facts to inject to other aggregates. Each EventBook targets a specific aggregate via its Cover. |
ProcessManagerPrepareRequest
Phase 1 request: PM declares additional destinations needed.
| Field | Type | Label | Description |
|---|
| trigger | EventBook | | Full state of triggering domain (by correlation_id). |
| process_state | EventBook | | Current process manager state (by correlation_id). May be empty for new workflow. |
ProcessManagerPrepareResponse
Phase 1 response: destinations to fetch before Handle.
| Field | Type | Label | Description |
|---|
| destinations | Cover | repeated | Additional aggregates needed beyond trigger. Query by correlation_id. Minimize fetches - only declare what's actually needed. |
SpeculatePmRequest
Request for speculative PM execution.
ProcessManagerCoordinatorService
ProcessManagerCoordinatorService: orchestrates PM execution
ProcessManagerService
ProcessManagerService: stateful coordinator for long-running workflows across multiple aggregates.
WARNING: Only use when saga + queries is insufficient. Consider:
- Can a simple saga + destination queries solve this?
- Is the "state" you want to track already derivable from existing aggregates?
- Are you adding Process Manager because the workflow is genuinely complex?
Process Manager is warranted when:
- Workflow state is NOT derivable from aggregates (PM owns unique state)
- You need to query workflow status independently ("show all pending fulfillments")
- Timeout/scheduling logic is complex enough to merit its own aggregate
- You must react to events from MULTIPLE domains (saga recommends single domain)
Process Manager IS an aggregate with its own domain, events, and state.
It reuses all aggregate infrastructure (EventStore, SnapshotStore, AggregateCoordinator).
Top
angzarr/projector.proto
SpeculateProjectorRequest
Request for speculative projector execution.
ProjectorCoordinatorService
ProjectorCoordinatorService: orchestrates projection processing
ProjectorService
ProjectorService: client logic that projects events to read models
client logic doesn't care about sync - coordinator decides
| Method Name | Request Type | Response Type | Description |
|---|
| Handle | EventBook | Projection | Async projection - projector should persist and return |
| HandleSpeculative | EventBook | Projection | Speculative processing - projector must avoid external side effects |
Top
angzarr/query.proto
EventQueryService
EventQueryService: query interface for retrieving events
| Method Name | Request Type | Response Type | Description |
|---|
| GetEventBook | Query | EventBook | Get a single EventBook (unary) - use for explicit queries with gRPC tooling |
| GetEvents | Query | EventBook stream | Stream EventBooks matching query - use for bulk retrieval (SSE) |
| Synchronize | Query stream | EventBook stream | Bidirectional sync - not exposed via REST (use gRPC directly) |
| GetAggregateRoots | .google.protobuf.Empty | AggregateRoot stream | List all aggregate roots (SSE) |
Top
angzarr/saga.proto
SagaCompensationFailed
System event when compensation fails/requested
| Field | Type | Label | Description |
|---|
| triggering_aggregate | Cover | | |
| triggering_event_sequence | uint32 | | |
| saga_name | string | | |
| rejection_reason | string | | |
| compensation_failure_reason | string | | |
| rejected_command | CommandBook | | |
| occurred_at | google.protobuf.Timestamp | | |
SagaExecuteRequest
| Field | Type | Label | Description |
|---|
| source | EventBook | | Source events (same as prepare) |
| destinations | EventBook | repeated | Fetched destination state |
SagaPrepareRequest
Two-phase saga protocol messages
| Field | Type | Label | Description |
|---|
| source | EventBook | | Source events that triggered the saga |
SagaPrepareResponse
| Field | Type | Label | Description |
|---|
| destinations | Cover | repeated | Destination aggregates the saga needs to read |
SagaResponse
Response from saga - commands for other aggregates
| Field | Type | Label | Description |
|---|
| commands | CommandBook | repeated | Commands to execute on other aggregates |
| events | EventBook | repeated | Events to publish directly |
SagaRetryRequest
SpeculateSagaRequest
Request for speculative saga execution.
SagaCoordinatorService
SagaCoordinatorService: orchestrates saga execution
SagaService
SagaService: client logic that coordinates across aggregates
Two-phase protocol: Prepare (declare destinations) → Execute (with fetched state)
Top
angzarr/stream.proto
EventStreamService
docs:start:event_stream_service
EventStreamService: streams events to registered subscribers
| Method Name | Request Type | Response Type | Description |
|---|
| Subscribe | EventStreamFilter | EventBook stream | Subscribe to events matching correlation ID (required) Returns INVALID_ARGUMENT if correlation_id is empty REST: Server-Sent Events (SSE) stream |
Top
angzarr/types.proto
AggregateRoot
| Field | Type | Label | Description |
|---|
| domain | string | | |
| root | UUID | | |
AngzarrDeadLetter
docs:start:dead_letter
Dead letter queue entry for failed messages requiring manual intervention.
Per-domain topics: angzarr.dlq.{domain}
AngzarrDeadLetter.MetadataEntry
| Field | Type | Label | Description |
|---|
| key | string | | |
| value | string | | |
CommandBook
Tracks origin for compensation flow |
CommandPage
| Field | Type | Label | Description |
|---|
| sequence | uint32 | | Expected sequence number for this command's events. Must match the aggregate's current next sequence (i.e., events.len()). For new aggregates, use 0. |
| merge_strategy | MergeStrategy | | |
| command | google.protobuf.Any | | |
| external | PayloadReference | | Claim check: payload stored externally |
CommandRequest
Request wrapper for command operations.
Adds execution metadata (sync_mode) to CommandBook.
ComponentDescriptor
Component self-description.
| Field | Type | Label | Description |
|---|
| name | string | | |
| component_type | string | | |
| inputs | Target | repeated | Domains I subscribe to (event types I consume) |
ContextualCommand
| Field | Type | Label | Description |
|---|
| events | EventBook | | Passed from aggregate coordinator to aggregate, consists of everything needed to execute/evaluate the command |
| command | CommandBook | | |
ContextualCommandRequest
Request wrapper for contextual command operations (internal use).
Adds execution metadata (sync_mode) to ContextualCommand.
Cover
docs:start:cover
| Field | Type | Label | Description |
|---|
| domain | string | | |
| root | UUID | | |
| correlation_id | string | | Workflow correlation - flows through all commands/events |
| edition | Edition | | Edition for diverged timelines; empty name = main timeline |
| external_id | string | | Idempotency key for fact events (e.g., Stripe payment ID, tracking number) |
DomainDivergence
Explicit divergence point for a specific domain.
Used when creating historical branches or coordinating saga writes across domains.
| Field | Type | Label | Description |
|---|
| domain | string | | Domain name |
| sequence | uint32 | | Divergence sequence number |
Edition
docs:start:edition
Edition identifier with optional explicit divergence points.
Two modes:
- Implicit (divergences empty): Divergence derived from first edition event's sequence
- Explicit (divergences populated): Per-domain divergence points for historical branching,
saga coordination, or speculative execution
| Field | Type | Label | Description |
|---|
| name | string | | Edition name, e.g., "v2"; empty = main timeline |
| divergences | DomainDivergence | repeated | Optional: explicit per-domain divergence points |
EventBook
docs:start:event_book
| Field | Type | Label | Description |
|---|
| cover | Cover | | |
| snapshot | Snapshot | | Snapshot state; sequence computed by framework on persist |
| pages | EventPage | repeated | |
| next_sequence | uint32 | | Field 4 removed: correlation_id moved to Cover Field 5 removed: snapshot_state unified into snapshot field |
Computed on load, never stored: (last page seq OR snapshot seq if no pages) + 1 |
EventPage
docs:start:event_page
EventProcessingFailedDetails
Event processing failure details for DLQ entries.
Contains information about why a saga/projector failed to process events.
| Field | Type | Label | Description |
|---|
| error | string | | Error message from the handler |
| retry_count | uint32 | | Number of retry attempts before DLQ routing |
| is_transient | bool | | Whether the failure is considered transient |
EventRequest
Request wrapper for event operations (fact injection).
Adds execution metadata (sync_mode, route_to_handler) to EventBook.
| Field | Type | Label | Description |
|---|
| events | EventBook | | |
| sync_mode | SyncMode | | |
| route_to_handler | bool | | For fact injection: when true (default), invokes command handler's handle_fact for validation/error checking before persistence. Facts cannot be rejected, but the handler can validate data integrity and log warnings. When false, facts are persisted directly without handler involvement. |
EventStreamFilter
docs:start:event_stream_filter
Subscription filter for event streaming
| Field | Type | Label | Description |
|---|
| correlation_id | string | | |
FactSequence
docs:start:fact_sequence
Marker for fact events - external realities that must be recorded.
Facts are events that already happened in the external world and cannot be rejected.
The coordinator assigns the actual sequence number on receipt.
IMPORTANT: When using FactSequence, set Cover.external_id for idempotency.
The coordinator uses Cover.external_id to deduplicate fact events.
Cover.external_id propagates through the entire system for tracing.
| Field | Type | Label | Description |
|---|
| source | string | | Origin system identifier (e.g., "stripe", "fedex", "scheduler") |
| description | string | | Human-readable description of why this is a fact (optional) |
GetDescriptorRequest
Request for GetDescriptor RPC.
Notification
docs:start:notification
Base notification message for transient system signals.
Contains routing info via Cover but no persistence semantics.
Type discrimination via payload.type_url (standard Any behavior).
Notification.MetadataEntry
| Field | Type | Label | Description |
|---|
| key | string | | |
| value | string | | |
PayloadReference
Reference to externally stored payload (claim check pattern).
Used when event/command payloads exceed message bus size limits.
| Field | Type | Label | Description |
|---|
| storage_type | PayloadStorageType | | |
| uri | string | | Location URI: - file:///var/angzarr/payloads/{hash}.bin - gs://bucket/prefix/{hash}.bin - s3://bucket/prefix/{hash}.bin |
| content_hash | bytes | | Content hash for integrity verification and deduplication (SHA-256) |
| original_size | uint64 | | Original serialized payload size in bytes |
| stored_at | google.protobuf.Timestamp | | Timestamp when payload was stored (for TTL cleanup) |
PayloadRetrievalFailedDetails
Payload retrieval failure details for DLQ entries.
Contains information about why an externally stored payload couldn't be retrieved.
| Field | Type | Label | Description |
|---|
| storage_type | PayloadStorageType | | Storage backend type |
| uri | string | | URI of the payload that couldn't be retrieved |
| content_hash | bytes | | Content hash for identification |
| original_size | uint64 | | Original payload size in bytes |
| error | string | | Error message from the retrieval attempt |
Projection
Query
RejectionNotification
docs:start:rejection_notification
Notification payload for command rejection scenarios.
Embedded in Notification.payload when a saga/PM command is rejected.
| Field | Type | Label | Description |
|---|
| rejected_command | CommandBook | | The command that was rejected (full context) |
| rejection_reason | string | | Why: "insufficient_funds", "out_of_stock", etc. |
| issuer_name | string | | Saga/PM name that issued the command |
| issuer_type | string | | "saga" |
| source_aggregate | Cover | | Aggregate that originally triggered the flow |
| source_event_sequence | uint32 | | Event sequence that triggered the saga/PM |
SagaCommandOrigin
Track saga command origin for compensation flow
| Field | Type | Label | Description |
|---|
| saga_name | string | | Name of the saga that issued the command |
| triggering_aggregate | Cover | | Domain+root of aggregate that triggered the saga |
| triggering_event_sequence | uint32 | | Sequence number of the triggering event |
SequenceMismatchDetails
docs:start:dlq_details
Sequence mismatch details for DLQ entries.
Contains expected vs actual sequence for debugging and replay.
| Field | Type | Label | Description |
|---|
| expected_sequence | uint32 | | What the command expected |
| actual_sequence | uint32 | | What the aggregate was at |
| merge_strategy | MergeStrategy | | Strategy that triggered DLQ routing |
SequenceRange
Query types
| Field | Type | Label | Description |
|---|
| lower | uint32 | | |
| upper | uint32 | optional | If not set, query to latest |
SequenceSet
| Field | Type | Label | Description |
|---|
| values | uint32 | repeated | |
Snapshot
docs:start:aggregate_snapshot
Snapshot of aggregate state at a given sequence number.
State must be a protobuf Message to serialize into Any.
Target
Describes what a component subscribes to.
Topology edges derived from inputs: if A subscribes to domain X, edge X→A exists.
| Field | Type | Label | Description |
|---|
| domain | string | | |
TemporalQuery
Temporal query: retrieve aggregate state at a point in history.
Replays events from sequence 0 (no snapshots) to the specified point.
| Field | Type | Label | Description |
|---|
| as_of_time | google.protobuf.Timestamp | | Events with created_at <= this |
| as_of_sequence | uint32 | | Events with sequence <= this |
UUID
| Field | Type | Label | Description |
|---|
| value | bytes | | |
MergeStrategy
docs:start:merge_strategy
Controls how concurrent commands to the same aggregate are handled
| Name | Number | Description |
|---|
| MERGE_COMMUTATIVE | 0 | Default: allow if state field mutations don't overlap |
| MERGE_STRICT | 1 | Reject if sequence mismatch (optimistic concurrency) |
| MERGE_AGGREGATE_HANDLES | 2 | Aggregate handles its own concurrency |
| MERGE_MANUAL | 3 | Send to DLQ for manual review on mismatch |
PayloadStorageType
docs:start:payload_reference
Storage backend type for externally stored payloads (claim check pattern).
| Name | Number | Description |
|---|
| PAYLOAD_STORAGE_TYPE_UNSPECIFIED | 0 | |
| PAYLOAD_STORAGE_TYPE_FILESYSTEM | 1 | |
| PAYLOAD_STORAGE_TYPE_GCS | 2 | |
| PAYLOAD_STORAGE_TYPE_S3 | 3 | |
SnapshotRetention
docs:start:snapshot_retention
Controls snapshot retention during cleanup
| Name | Number | Description |
|---|
| RETENTION_DEFAULT | 0 | Persist every 16 events, treated as TRANSIENT otherwise |
| RETENTION_PERSIST | 1 | Keep indefinitely (business milestone) |
| RETENTION_TRANSIENT | 2 | Delete when newer snapshot written |
SyncMode
docs:start:sync_mode
Controls synchronous processing behavior
| Name | Number | Description |
|---|
| SYNC_MODE_UNSPECIFIED | 0 | Async: fire and forget (default) |
| SYNC_MODE_SIMPLE | 1 | Sync projectors only, no saga cascade |
| SYNC_MODE_CASCADE | 2 | Full sync: projectors + saga cascade (expensive) |
Top
angzarr/upcaster.proto
UpcastRequest
| Field | Type | Label | Description |
|---|
| domain | string | | |
| events | EventPage | repeated | |
UpcastResponse
| Field | Type | Label | Description |
|---|
| events | EventPage | repeated | |
UpcasterService
UpcasterService: transforms old event versions to current versions
Implemented by the client alongside AggregateService on the same gRPC server.
Optionally can be deployed as a separate binary for testing or complex migrations.
| Method Name | Request Type | Response Type | Description |
|---|
| Upcast | UpcastRequest | UpcastResponse | Transform events to current version Returns events in same order, transformed where applicable |
Top
examples/ai_sidecar.proto
ActionHistory
ActionRequest
| Field | Type | Label | Description |
|---|
| model_id | string | | Game state |
Which model to use |
| game_variant | GameVariant | | |
| phase | BettingPhase | | |
| hole_cards | Card | repeated | Cards |
| community_cards | Card | repeated | |
| pot_size | int64 | | Betting context |
| stack_size | int64 | | |
| amount_to_call | int64 | | |
| min_raise | int64 | | |
| max_raise | int64 | | |
| position | int32 | | Position info
0 = button, increasing = earlier |
| players_remaining | int32 | | |
| players_to_act | int32 | | |
| action_history | ActionHistory | repeated | Historical context (for recurrent models) |
| opponents | OpponentStats | repeated | Opponent modeling (optional) |
ActionResponse
| Field | Type | Label | Description |
|---|
| recommended_action | ActionType | | |
| amount | int64 | | For bet/raise |
| fold_probability | float | | Confidence scores for each action (for analysis) |
| check_call_probability | float | | |
| bet_raise_probability | float | | |
| model_version | string | | Model metadata |
| inference_time_ms | int64 | | |
BatchActionRequest
BatchActionResponse
HealthRequest
HealthResponse
| Field | Type | Label | Description |
|---|
| healthy | bool | | |
| model_id | string | | |
| model_version | string | | |
| uptime_seconds | int64 | | |
| requests_served | int64 | | |
OpponentStats
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| position | int32 | | |
| stack | int64 | | |
| vpip | float | | Voluntarily put in pot % |
| pfr | float | | Pre-flop raise % |
| aggression | float | | Bet/raise frequency |
| hands_played | int32 | | |
AiSidecar
Top
examples/hand.proto
ActionTaken
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| action | ActionType | | |
| amount | int64 | | |
| player_stack | int64 | | Absolute stack after action |
| pot_total | int64 | | Absolute pot after action |
| amount_to_call | int64 | | Current call amount for next player |
| action_at | google.protobuf.Timestamp | | |
AwardPot
| Field | Type | Label | Description |
|---|
| awards | PotAward | repeated | |
BettingRoundComplete
BlindPosted
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| blind_type | string | | |
| amount | int64 | | |
| player_stack | int64 | | Absolute stack after posting |
| pot_total | int64 | | Absolute pot after posting |
| posted_at | google.protobuf.Timestamp | | |
CardsDealt
CardsMucked
CardsRevealed
DealCards
| Field | Type | Label | Description |
|---|
| table_root | bytes | | |
| hand_number | int64 | | |
| game_variant | GameVariant | | |
| players | PlayerInHand | repeated | |
| dealer_position | int32 | | |
| small_blind | int64 | | |
| big_blind | int64 | | |
| deck_seed | bytes | | For deterministic shuffle (testing) |
| Field | Type | Label | Description |
|---|
| count | int32 | | 3 for flop, 1 for turn/river |
DrawCompleted
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| cards_discarded | int32 | | |
| cards_drawn | int32 | | |
| new_cards | Card | repeated | Only visible to this player |
| drawn_at | google.protobuf.Timestamp | | |
HandComplete
HandState
State (for snapshots)
| Field | Type | Label | Description |
|---|
| hand_id | string | | |
| table_root | bytes | | |
| hand_number | int64 | | |
| game_variant | GameVariant | | |
| remaining_deck | Card | repeated | Deck state |
| players | PlayerHandState | repeated | Player state |
| community_cards | Card | repeated | Community cards |
| current_phase | BettingPhase | | Betting state |
| action_on_position | int32 | | |
| current_bet | int64 | | |
| min_raise | int64 | | |
| pots | Pot | repeated | |
| dealer_position | int32 | | Positions |
| small_blind_position | int32 | | |
| big_blind_position | int32 | | |
| status | string | | "dealing", "betting", "showdown", "complete" |
PlayerAction
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| action | ActionType | | |
| amount | int64 | | For bet/raise/call |
PlayerHandState
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| position | int32 | | |
| hole_cards | Card | repeated | |
| stack | int64 | | |
| bet_this_round | int64 | | |
| total_invested | int64 | | |
| has_acted | bool | | |
| has_folded | bool | | |
| is_all_in | bool | | |
PlayerHoleCards
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| cards | Card | repeated | |
PlayerInHand
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| position | int32 | | |
| stack | int64 | | |
PlayerStackSnapshot
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| stack | int64 | | |
| is_all_in | bool | | |
| has_folded | bool | | |
PlayerTimedOut
PostBlind
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| blind_type | string | | "small", "big", "ante" |
| amount | int64 | | |
PotAward
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| amount | int64 | | |
| pot_type | string | | |
PotAwarded
PotWinner
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| amount | int64 | | |
| pot_type | string | | |
| winning_hand | HandRanking | | |
RequestDraw
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| card_indices | int32 | repeated | Which cards to discard (0-indexed) |
RevealCards
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| muck | bool | | True to hide cards (fold at showdown) |
ShowdownStarted
Top
examples/player.proto
ActionRequested
Emitted when action is needed - AI players respond via sidecar
DepositFunds
FundsDeposited
FundsReleased
FundsReserved
FundsTransferred
FundsWithdrawn
PlayerRegistered
PlayerReturningToPlay
Player has chosen to return to play at a table
PlayerSittingOut
Player has chosen to sit out at a table
PlayerState
State (for snapshots)
PlayerState.TableReservationsEntry
| Field | Type | Label | Description |
|---|
| key | string | | |
| value | int64 | | |
RegisterPlayer
| Field | Type | Label | Description |
|---|
| display_name | string | | |
| email | string | | Used for root derivation |
| player_type | PlayerType | | HUMAN or AI |
| ai_model_id | string | | For AI players: which model to use |
ReleaseFunds
Release reserved funds back to bankroll (leave table)
| Field | Type | Label | Description |
|---|
| table_root | bytes | | |
RequestAction
Request action from player (triggers AI sidecar for AI players)
| Field | Type | Label | Description |
|---|
| hand_root | bytes | | |
| table_root | bytes | | |
| amount_to_call | int64 | | |
| min_raise | int64 | | |
| max_raise | int64 | | Player's remaining stack |
| hole_cards | Card | repeated | |
| community_cards | Card | repeated | |
| pot_size | int64 | | |
| phase | BettingPhase | | |
| timeout_seconds | int32 | | |
ReserveFunds
Reserve funds when joining a table (buy-in)
| Field | Type | Label | Description |
|---|
| amount | Currency | | |
| table_root | bytes | | Which table the funds are reserved for |
SitIn
Player decides to return to play at a table
| Field | Type | Label | Description |
|---|
| table_root | bytes | | |
SitOut
Player decides to sit out at a table (stop receiving hands)
| Field | Type | Label | Description |
|---|
| table_root | bytes | | |
TransferFunds
Transfer funds from one player to another (pot award)
| Field | Type | Label | Description |
|---|
| from_player_root | bytes | | Source player (for reserved funds) |
| amount | Currency | | |
| hand_root | bytes | | Which hand this transfer is for |
| reason | string | | "pot_win", "side_pot_win", etc. |
WithdrawFunds
Top
examples/poker_types.proto
Card
Card representation
| Field | Type | Label | Description |
|---|
| suit | Suit | | |
| rank | Rank | | |
Currency
Currency amount (in smallest unit, e.g., cents)
| Field | Type | Label | Description |
|---|
| amount | int64 | | |
| currency_code | string | | "USD", "EUR", "CHIPS" |
HandRanking
Hand ranking result
| Field | Type | Label | Description |
|---|
| rank_type | HandRankType | | |
| kickers | Rank | repeated | For tie-breaking |
| score | int32 | | Numeric score for comparison |
Pot
Pot structure (for side pots)
| Field | Type | Label | Description |
|---|
| amount | int64 | | |
| eligible_players | bytes | repeated | Player roots eligible for this pot |
| pot_type | string | | "main" or "side_N" |
Seat
Position at table
| Field | Type | Label | Description |
|---|
| position | int32 | | 0-9 for 10-max table |
| player_root | bytes | | Player aggregate root |
| stack | Currency | | Current stack at table |
| is_active | bool | | Still in current hand |
| is_sitting_out | bool | | Temporarily away |
ActionType
Player action type
| Name | Number | Description |
|---|
| ACTION_UNSPECIFIED | 0 | |
| FOLD | 1 | |
| CHECK | 2 | |
| CALL | 3 | |
| BET | 4 | |
| RAISE | 5 | |
| ALL_IN | 6 | |
BettingPhase
Betting round phase
| Name | Number | Description |
|---|
| BETTING_PHASE_UNSPECIFIED | 0 | |
| PREFLOP | 1 | |
| FLOP | 2 | |
| TURN | 3 | |
| RIVER | 4 | |
| DRAW | 5 | For draw games |
| SHOWDOWN | 6 | |
GameVariant
Game variant configuration
| Name | Number | Description |
|---|
| GAME_VARIANT_UNSPECIFIED | 0 | |
| TEXAS_HOLDEM | 1 | |
| OMAHA | 2 | |
| FIVE_CARD_DRAW | 3 | |
| SEVEN_CARD_STUD | 4 | |
HandRankType
| Name | Number | Description |
|---|
| HAND_RANK_UNSPECIFIED | 0 | |
| HIGH_CARD | 1 | |
| PAIR | 2 | |
| TWO_PAIR | 3 | |
| THREE_OF_A_KIND | 4 | |
| STRAIGHT | 5 | |
| FLUSH | 6 | |
| FULL_HOUSE | 7 | |
| FOUR_OF_A_KIND | 8 | |
| STRAIGHT_FLUSH | 9 | |
| ROYAL_FLUSH | 10 | |
PlayerType
Player type - abstraction for human vs AI
| Name | Number | Description |
|---|
| PLAYER_TYPE_UNSPECIFIED | 0 | |
| HUMAN | 1 | |
| AI | 2 | |
Rank
| Name | Number | Description |
|---|
| RANK_UNSPECIFIED | 0 | |
| TWO | 2 | |
| THREE | 3 | |
| FOUR | 4 | |
| FIVE | 5 | |
| SIX | 6 | |
| SEVEN | 7 | |
| EIGHT | 8 | |
| NINE | 9 | |
| TEN | 10 | |
| JACK | 11 | |
| QUEEN | 12 | |
| KING | 13 | |
| ACE | 14 | |
Suit
| Name | Number | Description |
|---|
| SUIT_UNSPECIFIED | 0 | |
| CLUBS | 1 | |
| DIAMONDS | 2 | |
| HEARTS | 3 | |
| SPADES | 4 | |
Top
examples/table.proto
AddChips
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| amount | int64 | | |
ChipsAdded
CreateTable
| Field | Type | Label | Description |
|---|
| table_name | string | | |
| game_variant | GameVariant | | |
| small_blind | int64 | | |
| big_blind | int64 | | |
| min_buy_in | int64 | | |
| max_buy_in | int64 | | |
| max_players | int32 | | 2-10 |
| action_timeout_seconds | int32 | | |
EndHand
| Field | Type | Label | Description |
|---|
| hand_root | bytes | | |
| results | PotResult | repeated | |
HandEnded
HandEnded.StackChangesEntry
| Field | Type | Label | Description |
|---|
| key | string | | |
| value | int64 | | |
HandStarted
| Field | Type | Label | Description |
|---|
| hand_root | bytes | | New hand aggregate root |
| hand_number | int64 | | |
| dealer_position | int32 | | |
| small_blind_position | int32 | | |
| big_blind_position | int32 | | |
| active_players | SeatSnapshot | repeated | |
| game_variant | GameVariant | | |
| small_blind | int64 | | |
| big_blind | int64 | | |
| started_at | google.protobuf.Timestamp | | |
JoinTable
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| preferred_seat | int32 | | -1 for any available |
| buy_in_amount | int64 | | |
LeaveTable
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
PlayerJoined
| Field | Type | Label | Description |
|---|
| player_root | bytes | | |
| seat_position | int32 | | |
| buy_in_amount | int64 | | |
| stack | int64 | | Absolute stack after buy-in |
| joined_at | google.protobuf.Timestamp | | |
PlayerLeft
PlayerSatIn
PlayerSatOut
PotResult
| Field | Type | Label | Description |
|---|
| winner_root | bytes | | |
| amount | int64 | | |
| pot_type | string | | "main" or "side_N" |
| winning_hand | HandRanking | | |
SeatSnapshot
| Field | Type | Label | Description |
|---|
| position | int32 | | |
| player_root | bytes | | |
| stack | int64 | | |
StartHand
No parameters - uses current table state
Dealer button advances automatically
TableCreated
| Field | Type | Label | Description |
|---|
| table_name | string | | |
| game_variant | GameVariant | | |
| small_blind | int64 | | |
| big_blind | int64 | | |
| min_buy_in | int64 | | |
| max_buy_in | int64 | | |
| max_players | int32 | | |
| action_timeout_seconds | int32 | | |
| created_at | google.protobuf.Timestamp | | |
TableState
State (for snapshots)
| Field | Type | Label | Description |
|---|
| table_id | string | | |
| table_name | string | | |
| game_variant | GameVariant | | |
| small_blind | int64 | | |
| big_blind | int64 | | |
| min_buy_in | int64 | | |
| max_buy_in | int64 | | |
| max_players | int32 | | |
| action_timeout_seconds | int32 | | |
| seats | Seat | repeated | |
| dealer_position | int32 | | |
| hand_count | int64 | | |
| current_hand_root | bytes | | |
| status | string | | "waiting", "in_hand", "paused" |
Top
google/api/annotations.proto
File-level Extensions
| Extension | Type | Base | Number | Description |
|---|
| http | HttpRule | .google.protobuf.MethodOptions | 72295728 | See HttpRule. |
Top
google/api/http.proto
CustomHttpPattern
A custom pattern is used for defining custom HTTP verb.
| Field | Type | Label | Description |
|---|
| kind | string | | The name of this custom HTTP verb. |
| path | string | | The path matched by this custom verb. |
Http
Defines the HTTP configuration for an API service. It contains a list of
[HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
to one or more HTTP REST API methods.
| Field | Type | Label | Description |
|---|
| rules | HttpRule | repeated | A list of HTTP configuration rules that apply to individual API methods. |
NOTE: All service configuration rules follow "last one wins" order. |
| fully_decode_reserved_expansion | bool | | When set to true, URL path parameters will be fully URI-decoded except in cases of single segment matches in reserved expansion, where "%2F" will be left encoded.
The default behavior is to not decode RFC 6570 reserved characters in multi segment matches. |
HttpRule
gRPC Transcoding
gRPC Transcoding is a feature for mapping between a gRPC method and one or
more HTTP REST endpoints. It allows developers to build a single API service
that supports both gRPC APIs and REST APIs. Many systems, including Google
APIs,
Cloud Endpoints, gRPC
Gateway,
and Envoy proxy support this feature
and use it for large scale production services.
HttpRule defines the schema of the gRPC/REST mapping. The mapping specifies
how different portions of the gRPC request message are mapped to the URL
path, URL query parameters, and HTTP request body. It also controls how the
gRPC response message is mapped to the HTTP response body. HttpRule is
typically specified as an google.api.http annotation on the gRPC method.
Each mapping specifies a URL path template and an HTTP method. The path
template may refer to one or more fields in the gRPC request message, as long
as each field is a non-repeated field with a primitive (non-message) type.
The path template controls how fields of the request message are mapped to
the URL path.
Example:
service Messaging {
rpc GetMessage(GetMessageRequest) returns (Message) {
option (google.api.http) = {
get: "/v1/{name=messages/*}"
};
}
}
message GetMessageRequest {
string name = 1; // Mapped to URL path.
}
message Message {
string text = 1; // The resource content.
}
This enables an HTTP REST to gRPC mapping as below:
- HTTP:
GET /v1/messages/123456
- gRPC:
GetMessage(name: "messages/123456")
Any fields in the request message which are not bound by the path template
automatically become HTTP query parameters if there is no HTTP request body.
For example:
service Messaging {
rpc GetMessage(GetMessageRequest) returns (Message) {
option (google.api.http) = {
get:"/v1/messages/{message_id}"
};
}
}
message GetMessageRequest {
message SubMessage {
string subfield = 1;
}
string message_id = 1; // Mapped to URL path.
int64 revision = 2; // Mapped to URL query parameter revision.
SubMessage sub = 3; // Mapped to URL query parameter sub.subfield.
}
This enables a HTTP JSON to RPC mapping as below:
- HTTP:
GET /v1/messages/123456?revision=2&sub.subfield=foo
- gRPC:
GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))
Note that fields which are mapped to URL query parameters must have a
primitive type or a repeated primitive type or a non-repeated message type.
In the case of a repeated type, the parameter can be repeated in the URL
as ...?param=A&param=B. In the case of a message type, each field of the
message is mapped to a separate parameter, such as
...?foo.a=A&foo.b=B&foo.c=C.
For HTTP methods that allow a request body, the body field
specifies the mapping. Consider a REST update method on the
message resource collection:
service Messaging {
rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
option (google.api.http) = {
patch: "/v1/messages/{message_id}"
body: "message"
};
}
}
message UpdateMessageRequest {
string message_id = 1; // mapped to the URL
Message message = 2; // mapped to the body
}
The following HTTP JSON to RPC mapping is enabled, where the
representation of the JSON in the request body is determined by
protos JSON encoding:
- HTTP:
PATCH /v1/messages/123456 \{ "text": "Hi!" \}
- gRPC:
UpdateMessage(message_id: "123456" message \{ text: "Hi!" \})
The special name * can be used in the body mapping to define that
every field not bound by the path template should be mapped to the
request body. This enables the following alternative definition of
the update method:
service Messaging {
rpc UpdateMessage(Message) returns (Message) {
option (google.api.http) = {
patch: "/v1/messages/{message_id}"
body: "*"
};
}
}
message Message {
string message_id = 1;
string text = 2;
}
The following HTTP JSON to RPC mapping is enabled:
- HTTP:
PATCH /v1/messages/123456 \{ "text": "Hi!" \}
- gRPC:
UpdateMessage(message_id: "123456" text: "Hi!")
Note that when using * in the body mapping, it is not possible to
have HTTP parameters, as all fields not bound by the path end in
the body. This makes this option more rarely used in practice when
defining REST APIs. The common usage of * is in custom methods
which don't use the URL at all for transferring data.
It is possible to define multiple HTTP methods for one RPC by using
the additional_bindings option. Example:
service Messaging {
rpc GetMessage(GetMessageRequest) returns (Message) {
option (google.api.http) = {
get: "/v1/messages/{message_id}"
additional_bindings {
get: "/v1/users/{user_id}/messages/{message_id}"
}
};
}
}
message GetMessageRequest {
string message_id = 1;
string user_id = 2;
}
This enables the following two alternative HTTP JSON to RPC mappings:
-
HTTP: GET /v1/messages/123456
-
gRPC: GetMessage(message_id: "123456")
-
HTTP: GET /v1/users/me/messages/123456
-
gRPC: GetMessage(user_id: "me" message_id: "123456")
Rules for HTTP mapping
- Leaf request fields (recursive expansion nested messages in the request
message) are classified into three categories:
- Fields referred by the path template. They are passed via the URL path.
- Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They
are passed via the HTTP
request body.
- All other fields are passed via the URL query parameters, and the
parameter name is the field path in the request message. A repeated
field can be represented as multiple query parameters under the same
name.
- If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL
query parameter, all fields
are passed via URL path and HTTP request body.
- If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP
request body, all
fields are passed via URL path and URL query parameters.
Path template syntax
Template = "/" Segments [ Verb ] ;
Segments = Segment { "/" Segment } ;
Segment = "*" | "**" | LITERAL | Variable ;
Variable = "{" FieldPath [ "=" Segments ] "}" ;
FieldPath = IDENT { "." IDENT } ;
Verb = ":" LITERAL ;
The syntax * matches a single URL path segment. The syntax ** matches
zero or more URL path segments, which must be the last part of the URL path
except the Verb.
The syntax Variable matches part of the URL path as specified by its
template. A variable template must not contain other variables. If a variable
matches a single path segment, its template may be omitted, e.g. \{var\}
is equivalent to \{var=*\}.
The syntax LITERAL matches literal text in the URL path. If the LITERAL
contains any reserved character, such characters should be percent-encoded
before the matching.
If a variable contains exactly one path segment, such as "\{var\}" or
"\{var=*\}", when such a variable is expanded into a URL path on the client
side, all characters except [-_.~0-9a-zA-Z] are percent-encoded. The
server side does the reverse decoding. Such variables show up in the
Discovery
Document as
\{var\}.
If a variable contains multiple path segments, such as "\{var=foo/*\}"
or "\{var=**\}", when such a variable is expanded into a URL path on the
client side, all characters except [-_.~/0-9a-zA-Z] are percent-encoded.
The server side does the reverse decoding, except "%2F" and "%2f" are left
unchanged. Such variables show up in the
Discovery
Document as
\{+var\}.
Using gRPC API Service Configuration
gRPC API Service Configuration (service config) is a configuration language
for configuring a gRPC service to become a user-facing product. The
service config is simply the YAML representation of the google.api.Service
proto message.
As an alternative to annotating your proto file, you can configure gRPC
transcoding in your service config YAML files. You do this by specifying a
HttpRule that maps the gRPC method to a REST endpoint, achieving the same
effect as the proto annotation. This can be particularly useful if you
have a proto that is reused in multiple services. Note that any transcoding
specified in the service config will override any matching transcoding
configuration in the proto.
The following example selects a gRPC method and applies an HttpRule to it:
http:
rules:
- selector: example.v1.Messaging.GetMessage
get: /v1/messages/{message_id}/{sub.subfield}
Special notes
When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the
proto to JSON conversion must follow the proto3
specification.
While the single segment variable follows the semantics of
RFC 6570 Section 3.2.2 Simple String
Expansion, the multi segment variable does not follow RFC 6570 Section
3.2.3 Reserved Expansion. The reason is that the Reserved Expansion
does not expand special characters like ? and #, which would lead
to invalid URLs. As the result, gRPC Transcoding uses a custom encoding
for multi segment variables.
The path variables must not refer to any repeated or mapped field,
because client libraries are not capable of handling such variable expansion.
The path variables must not capture the leading "/" character. The reason
is that the most common use case "{var}" does not capture the leading "/"
character. For consistency, all path variables must share the same behavior.
Repeated message fields must not be mapped to URL query parameters, because
no client library can support such complicated mapping.
If an API needs to use a JSON array for request or response body, it can map
the request or response body to a repeated field. However, some gRPC
Transcoding implementations may not support this feature.
| Field | Type | Label | Description |
|---|
| selector | string | | Selects a method to which this rule applies. |
Refer to [selector][google.api.DocumentationRule.selector] for syntax details. |
| get | string | | Maps to HTTP GET. Used for listing and getting information about resources. |
| put | string | | Maps to HTTP PUT. Used for replacing a resource. |
| post | string | | Maps to HTTP POST. Used for creating a resource or performing an action. |
| delete | string | | Maps to HTTP DELETE. Used for deleting a resource. |
| patch | string | | Maps to HTTP PATCH. Used for updating a resource. |
| custom | CustomHttpPattern | | The custom pattern is used for specifying an HTTP method that is not included in the pattern field, such as HEAD, or "*" to leave the HTTP method unspecified for this rule. The wild-card rule is useful for services that provide content to Web (HTML) clients. |
| body | string | | The name of the request field whose value is mapped to the HTTP request body, or * for mapping all request fields not captured by the path pattern to the HTTP body, or omitted for not having any HTTP request body.
NOTE: the referred field must be present at the top-level of the request message type. |
| response_body | string | | Optional. The name of the response field whose value is mapped to the HTTP response body. When omitted, the entire response message will be used as the HTTP response body.
NOTE: The referred field must be present at the top-level of the response message type. |
| additional_bindings | HttpRule | repeated | Additional HTTP bindings for the selector. Nested bindings must not contain an additional_bindings field themselves (that is, the nesting may only be one level deep). |
Top
io/cloudevents/v1/cloudevents.proto
CloudEvent
CloudEvent represents a single CloudEvent in protobuf format.
| Field | Type | Label | Description |
|---|
| id | string | | Required Attributes |
| source | string | | URI-reference |
| spec_version | string | | |
| type | string | | |
| attributes | CloudEvent.AttributesEntry | repeated | Optional & Extension Attributes |
| binary_data | bytes | | Binary data |
| text_data | string | | Text data |
| proto_data | google.protobuf.Any | | Protobuf message |
CloudEvent.AttributesEntry
CloudEventAttributeValue
CloudEventAttributeValue supports the CloudEvents type system.
| Field | Type | Label | Description |
|---|
| ce_boolean | bool | | |
| ce_integer | int32 | | |
| ce_string | string | | |
| ce_bytes | bytes | | |
| ce_uri | string | | |
| ce_uri_ref | string | | |
| ce_timestamp | google.protobuf.Timestamp | | |
CloudEventBatch
CloudEventBatch is a container for multiple CloudEvents.
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) |