Key Concepts
May 16, 2026 · View on GitHub
This page walks through the core data types and patterns in OpenContracts. It is the recommended starting point for the walkthrough.
Data Types
OpenContracts organises knowledge into a small set of first-class entities:
- Documents — uploaded files. PDFs are the primary format (full layout and annotation fidelity via the Docling microservice); DOCX (Docxodus) and plain text (
.txt) are also supported. See Supported File Formats. - Corpuses — collections of documents. A document can live in zero or more corpuses. Corpuses can be nested into folder hierarchies (
CorpusFolder), forked from public corpuses, exported, imported, and version-controlled. - Annotations — text-level spans (highlighted text), document-level type labels, or token-level spans. Annotations can be created by humans, by analyzers, or by AI agents. Each annotation has a
LabelSet-scopedAnnotationLabel. - Relationships — directed edges between annotations, with their own
AnnotationLabel. Used for cross-references, parent/child structural relationships, and pre-materialisedOC_SUBTREE_GROUProws for efficient block-level retrieval. - Notes — long-form prose attached to a document or corpus. Distinct from annotations; intended for human-written commentary.
- Conversations & Threads — persistent chat history. Conversations come in two flavours:
CHAT(one-on-one chat with an AI agent) andTHREAD(forum-style discussion). Threads support voting, moderation, @-mentions, and agent participation. - Analyses — read-only annotation sets produced by a document analyzer (see analyzers documentation).
- Extracts / Fieldsets / Datacells — structured data extraction across documents. A
Fieldsetdefines columns (Columnrows) with prompts; running it against a corpus produces anExtractwith oneDatacellper (document, column). - Metadata — typed custom metadata fields with validation, attached to corpuses and documents. See Metadata Overview.
- Badges & Reputation — gamified recognition tied to community contributions. See Badge System.
- Corpus Actions — automation triggers. Run a fieldset, analyzer, or AI agent automatically when a document is added/edited or a new thread/message arrives. See Corpus Actions.
- Agent Configurations — saved configurations for AI agents (
AgentConfigurationmodel) with scope (GLOBALor corpus-scoped), tool allowlists, and approval policies.
Permissioning
OpenContracts uses django-guardian for per-object permissions, layered with custom queryset managers:
- Each
Model.objects.visible_to_user(user)returns the queryset of objects the user can see (public + owned + explicitly shared). - Annotations and Relationships do not carry individual permissions; access is inherited from the document and corpus they live in (effective permission =
min(document_permission, corpus_permission)). - Documents and Corpuses carry direct object-level permissions.
- Analyses and Extracts use a hybrid model (own permissions + corpus permissions + document filtering).
- Structural annotations (those bound to a
StructuralAnnotationSet) are read-only except for superusers.
The full guide is at Consolidated Permissioning Guide.
Sharing & Forking
Public visibility is a first-class UI feature: the corpus settings tab exposes a "make public" toggle, the corpus card shows the visibility badge, and anyone can fork a public corpus from the corpus home page. Forking is now implemented as export-V2 → import-V2 so the fork format is guaranteed to round-trip cleanly (see Corpus Forking).
Behind the UI, the underlying GraphQL mutations are setCorpusVisibility and startCorpusFork. The makeAnalysisPublic mutation is also available for analysis sharing.
GraphQL
OpenContracts uses Graphene to serve GraphQL. The GraphiQL playground lives at the application root URL /graphql/:
- Local development:
http://localhost:8000/graphql/ - Demo / production: e.g.,
https://contracts.opensource.legal/graphql/
Anonymous requests can see public data. To act as a user you can either log in to the Django admin (session cookie) or call the tokenAuth mutation to obtain a JWT.
The schema is checked into the repository at schema.graphql; GraphiQL's built-in docs explorer is the easiest way to browse types interactively.
WebSockets
Real-time streaming chat is delivered over Django Channels. Three consumer endpoints are exposed (see WebSocket Protocol):
ws/agent-chat/— unified agent conversation (document chat, corpus chat, standalone agent chat). Context is supplied via query parameters:?corpus_id=X,?document_id=X,?agent_id=X,?conversation_id=X.ws/thread-updates/— agent-mention streaming inside discussion threads. Requires?conversation_id=X.ws/notification-updates/— real-time notification push (badges, moderation events, agent responses).
All WebSocket connections are authenticated by the shared JWTAuthMiddleware, which handles both Django session auth and Auth0 JWTs.