---
title: "Singer (specification)"
description: "Singer is an open-source specification that defines how independent scripts, called taps and targets, communicate data and state using a simple JSON format over stdout and stdin."
canonical: "https://motherduck.com/glossary/singer-specification/"
related:
  - title: "DuckLake Architecture Deep Dive"
    url: "https://motherduck.com/blog/ducklake-architecture-deep-dive/"
  - title: "Sling | MotherDuck Docs"
    url: "https://motherduck.com/docs/integrations/ingestion/sling/"
  - title: "Language APIs & Drivers | MotherDuck Docs"
    url: "https://motherduck.com/docs/integrations/language-apis-and-drivers/"
---

# Singer (specification)

> Singer is an open-source specification that defines how independent scripts, called taps and targets, communicate data and state using a simple JSON format over stdout and stdin.

## Overview

Singer is an open specification, not a product, for moving data between systems. It defines a common protocol so that a data **extraction** script (a **tap**) and a data **loading** script (a **target**) can be written independently, by different people, in any language, and still work together as long as both follow the spec. Singer was created by Stitch (the company behind the Stitch Data Loader), which was acquired by Talend in 2018; Talend was in turn acquired by Qlik in 2023. The specification itself remains open source and is used by Meltano's ecosystem of community-maintained taps and targets, independent of any single vendor.

<glossary-callout video="agentic-data-engineering-pipelines-ai" />

## How it works

A Singer tap reads from a source and writes newline-delimited JSON messages to stdout. A target reads that same stream from stdin and writes it to a destination. Three message types carry the pipeline's contract:

- **SCHEMA**: describes the structure of an upcoming stream of records.
- **RECORD**: an individual row of data.
- **STATE**: a bookmark (e.g., an updated_at cursor or primary key) that lets the next run resume incrementally instead of reprocessing everything.

```bash
# a tap and target composed with a standard pipe
tap-postgres --config config.json | target-jsonl --config target-config.json
```

```json
{"type": "RECORD", "stream": "orders", "record": {"id": 101, "amount": 42.50, "updated_at": "2024-01-15T00:00:00Z"}}
{"type": "STATE", "value": {"bookmarks": {"orders": {"updated_at": "2024-01-15T00:00:00Z"}}}}
```

## Why it matters

Singer's stdout/stdin, JSON-based design means a tap and target never need to know about each other's implementation, only the shared message format — which is what let an ecosystem of community-built taps and targets grow independent of Stitch as a company. Meltano is the most active current steward of this open ecosystem, publishing and running Singer plugins through MeltanoHub. Since a Singer target can write to plain files or a database, a common pattern is a Singer/Meltano pipeline landing data as JSON or Parquet that is then queried directly with DuckDB, or loaded onward into MotherDuck for shared analytics.