# document

Create Document artifacts for static content

Canonical URL: https://docs.paradoc.dev/sdk/artifacts/document/

Create Document artifacts for disclosures, pamphlets, or any static content that can be rendered to different formats via layers.

## Examples

### Creating a document

```ts
// Object pattern
const doc = p.document({
  name: 'privacy-disclosure',
  version: '1.0.0',
  title: 'Privacy Disclosure',
  layers: {
    html: { kind: 'inline', mimeType: 'text/html', text: '<p>...</p>' }
  },
  defaultLayer: 'html'
})

// Builder pattern
const doc = p.document()
  .name('privacy-disclosure')
  .version('1.0.0')
  .title('Privacy Disclosure')
  .inlineLayer('html', { mimeType: 'text/html', text: '<p>...</p>' })
  .defaultLayer('html')
  .build()
```

### Loading from external data

```ts
// Parse and validate unknown input (throws on error)
const doc = p.document.from(jsonData)

// Safe parsing (returns result object)
const result = p.document.safeFrom(jsonData)
if (result.success) {
  const doc = result.data
}
```

## API

### Object Pattern

```ts
p.document(input: DocumentInput, options?: ArtifactInstanceOptions): DocumentInstance
```

`options.resolver` reads the bytes of any file-backed layer this document
declares. It's bound once here, at construction, and every instance derived
from the document — every mutator and `clone` — carries it; `render()` itself
takes no resolver. See [ArtifactInstanceOptions](/sdk/resolvers#artifactinstanceoptions).

#### Parameters

| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | Unique identifier; must follow slug constraints |
| `version?` | `string` | Artifact version (semantic versioning) |
| `title?` | `string` | Human-friendly name presented to end users |
| `description?` | `string` | Long-form description or context |
| `code?` | `string` | The form number as printed by its issuer (e.g. W-9, ACORD 25), or a self-issued form's own number |
| `language?` | `string` | BCP 47 source language tag; defaults to en when omitted |
| `issuer?` | `string` | Organization that issues the form |
| `edition?` | `ArtifactEdition` | Issuer edition: { key, label, date?, effectiveFrom? } |
| `metadata?` | `Metadata` | Custom metadata map (keys must be alphanumeric with hyphens) |
| `instructions?` | `ContentRef` | Domain or compliance reference content |
| `agentInstructions?` | `ContentRef` | LLM/agent prompts for presentation guidance |
| `layers?` | `Record<string, Layer>` | Named layers for rendering into different formats |
| `defaultLayer?` | `string` | Key of the default layer to use when none specified |

#### Returns

Returns a `DocumentInstance` with the following properties and methods:

| Name | Type | Description |
| --- | --- | --- |
| `kind` | `'document'` | Artifact discriminator |
| `name` | `string` | Document name |
| `version` | `string \| undefined` | Semantic version |
| `title` | `string \| undefined` | Human-readable title |
| `description` | `string \| undefined` | Description text |
| `code` | `string \| undefined` | The form number as printed by its issuer (e.g. W-9, ACORD 25), or a self-issued form's own number |
| `language` | `string \| undefined` | BCP 47 source language tag |
| `issuer` | `string \| undefined` | Issuing organization |
| `edition` | `ArtifactEdition \| undefined` | Issuer edition |
| `metadata` | `Metadata \| undefined` | Custom metadata map |
| `instructions` | `ContentRef \| undefined` | Domain or compliance reference content |
| `agentInstructions` | `ContentRef \| undefined` | LLM/agent prompts for presentation guidance |
| `layers` | `Record<string, Layer> \| undefined` | Render layers |
| `defaultLayer` | `string \| undefined` | Default layer key |

**Methods**

| Name | Type | Description |
| --- | --- | --- |
| `validate` | `(options?: ValidateOptions) => StandardSchemaV1.Result` | Validate the document definition |
| `isValid` | `(options?: ValidateOptions) => boolean` | Check if document is valid |
| `toJSON` | `(options?: SerializationOptions) => object` | Serialize to JSON (includes the current dated $schema by default) |
| `toYAML` | `(options?: SerializationOptions) => string` | Serialize to YAML (includes the current dated $schema by default) |
| `clone` | `() => DocumentInstance` | Deep clone the instance |
| `prepare` | `(targetLayer?: string) => DraftDocument` | Create a draft for a layer (defaults to defaultLayer) |
| `render` | `(options?: ArtifactLayerRenderOptions) => Promise<string \| Uint8Array>` | Render document content. See [Render options](#render-options) |

### Builder Pattern

Chain methods to build a document incrementally:

Start with `p.document()`. Each method returns `DocumentBuilder` and can be chained.

| Method | Description |
| --- | --- |
| `name(value: string)` | Set document name (required) |
| `version(value: string)` | Set semantic version |
| `title(value: string)` | Set human-readable title |
| `description(value: string)` | Set description |
| `code(value: string)` | Set external reference code |
| `language(value: string)` | Set source language (BCP 47 tag) |
| `issuer(value: string)` | Set the issuing organization |
| `edition({ key, label, date?, effectiveFrom? })` | Set the issuer edition |
| `metadata(value: Metadata)` | Set custom metadata |
| `instructions(value: ContentRef)` | Set domain/compliance reference content |
| `agentInstructions(value: ContentRef)` | Set LLM/agent presentation guidance |
| `layers(value: Record<string, Layer>)` | Set all layers at once |
| `layer(key: string, layer: Layer)` | Add a layer from a Layer object |
| `inlineLayer(key: string, layer: { mimeType, text, ... })` | Add inline text layer |
| `fileLayer(key: string, layer: { mimeType, path, ... })` | Add file-backed layer |
| `defaultLayer(key: string)` | Set default layer for rendering |

Terminal methods return `DocumentInstance`.

| Method | Description |
| --- | --- |
| `build(options?: ArtifactInstanceOptions)` | Build and validate; bind a resolver for file-backed layers |

### Static Methods

Parse documents from unknown data sources. Both accept an
[`ArtifactInstanceOptions`](/sdk/resolvers#artifactinstanceoptions) to bind a
resolver for any file-backed layer:

| Method | Returns | Description |
| --- | --- | --- |
| `from(input: unknown, options?: ArtifactInstanceOptions)` | `DocumentInstance` | Parse unknown input (throws on error) |
| `safeFrom(input: unknown, options?: ArtifactInstanceOptions)` | `Result<DocumentInstance>` | Parse unknown input (returns result object) |

## Lifecycle Types

Documents follow a two-phase lifecycle:

| Type            | Phase | Description                         |
| --------------- | ----- | ----------------------------------- |
| `DraftDocument` | Draft | Document ready for finalization     |
| `FinalDocument` | Final | Frozen document, ready for archival |

```ts
// Prepare document (DraftDocument)
const draft = doc.prepare('html')

// Finalize (FinalDocument)
const final = draft.finalize()

// final.finalizedAt === ISO timestamp
// Render
const output = await final.render()
```

### DraftDocument

Created by `doc.prepare()`.

| Name | Type | Description |
| --- | --- | --- |
| `phase` | `'draft'` | Phase discriminator |
| `document` | `Document` | The underlying document definition |
| `targetLayer` | `string` | Target layer key |

**Methods**

| Name | Type | Description |
| --- | --- | --- |
| `setTargetLayer` | `(layer: string) => DraftDocument` | Change the target layer |
| `finalize` | `() => FinalDocument` | Transition to final phase |
| `render` | `(options?: ArtifactLayerRenderOptions) => Promise<string \| Uint8Array>` | Render the document |
| `toJSON` | `() => DraftDocumentJSON` | Serialize to JSON |
| `toYAML` | `() => string` | Serialize to YAML |
| `clone` | `() => DraftDocument` | Create an exact copy |

### FinalDocument

Created by `draft.finalize()`. Fully frozen.

| Name | Type | Description |
| --- | --- | --- |
| `phase` | `'final'` | Phase discriminator |
| `finalizedAt` | `string` | ISO timestamp of finalization |

**Methods**

| Name | Type | Description |
| --- | --- | --- |
| `render` | `(options?: ArtifactLayerRenderOptions) => Promise<string \| Uint8Array>` | Render the document |
| `toJSON` | `() => FinalDocumentJSON` | Serialize to JSON |
| `toYAML` | `() => string` | Serialize to YAML |
| `clone` | `() => FinalDocument` | Create an exact copy |

## Render options

`render()` takes `ArtifactLayerRenderOptions`. A renderer registered for the layer's MIME type runs first. Otherwise a document layer returns its resolved content unchanged.

| Name | Type | Description |
| --- | --- | --- |
| `layer?` | `string` | Layer key to render. Defaults to the target layer, then defaultLayer |
| `renderers?` | `RendererRegistry` | Renderers keyed by layer MIME type |
| `formatter?` | `Formatter` | Formatter used for values in this render |
| `progressive?` | `FormatterProgressivePolicy` | Text for missing and incomplete values |

## Related

* [Document Schema](/schemas/artifacts/document)
* [Renderers](/sdk/renderers)
* [Formatting](/sdk/formatting)
