Skip to content

Introduction

EvidentSource is an API platform built on bi-temporal event sourcing. Every business action is captured as an immutable event — what happened, when it took effect, and when the system learned of it. From those events, the platform computes the State Views your application reads, and answers questions about the past that ordinary databases can’t.

If you’re here, you’re probably building something where the record of how a decision was made matters as much as the decision itself: financial systems, regulated workflows, or software that lets AI agents take actions on your behalf.

EvidentSource ships as three surfaces. You can enter the story from any of them.

A visual Event Modeling workspace. You draw your system as commands, events and State Views, and Designer generates a Rust project that implements it: a decide function for each command and an evolve function for each view, ready for your logic.

Use it when you want to think through a system’s behavior before writing code, or you want a model a non-engineer can read.

A free, hosted EvidentSource server. Publish an example, point any SDK (Rust, Go, TypeScript, .NET, Python) at it, and start issuing commands and reading State Views. There’s no signup.

The Sandbox exists to let you feel the API. Treat it as a public scratchpad: data is visible to everyone, gets purged on a schedule, and carries no availability or support guarantees. See About the Sandbox before you put anything into it.

Use it when you want to explore the API, validate an SDK integration, or demo something to a colleague without standing up infrastructure.

The runtime itself: a container backed by S3. Deploy it to your own AWS account through the AWS Marketplace when you’re ready to run your own workloads with real data, your own authentication, and your own durability expectations. See Operations: containers + S3.

Use it when you’ve outgrown the Sandbox and want EvidentSource in your own VPC.

Two functions.

  • decide, in a State Change, handles a command. It reads the database, checks the command, and returns the events to append, with the append conditions that must still hold when they commit.
  • evolve, in a State View, folds events into the state your application reads.
#[evidentsource_functions::state_change(name = "create-todo")]
fn decide(
_db: &Database,
command: CreateTodoCommand,
_metadata: &StateChangeMetadata,
) -> Result<(NonEmpty<DomainEvent>, Vec<AppendCondition>), StateChangeError> {
if command.title.trim().is_empty() {
return Err(StateChangeError::Validation("Todo title cannot be empty".into()));
}
let event = DomainEvent::TodoCreated {
todo_id: command.todo_id,
title: command.title,
effective_timestamp: command.effective_timestamp,
};
Ok((NonEmpty::new(event), vec![]))
}

There are no distributed transactions to reason about and no saga orchestrators to debug: a decision’s append conditions carry its consistency. You write a functional core, and the imperative shell around it is the platform’s job.

Read more in State Changes & State Views.

If you want to…Start here
Feel the API in a few minutesTry the Sandbox
Run a complete exampleSet up the TodoMVC example
Design a system before writing codeDesign your first system
Go from whiteboard to working appDesigner → Sandbox
Understand the ideasConcepts
Run EvidentSource yourselfOperations: containers + S3