# Evidence-Quoted Text Coder — Your Own Labels, Never Guesses (`equ1n0x/evidence-quoted-text-coder`) Actor

Give it your labels and your passages: each coded row carries the verbatim quote that earned it. Where it cannot tell, it hands back the named residual - the two labels it fell between, or an honest no-quote-held. Two readings must agree. No model weights, nothing leaves the container.

- **URL**: https://apify.com/equ1n0x/evidence-quoted-text-coder.md
- **Developed by:** [Noah Davidson](https://apify.com/equ1n0x) (community)
- **Categories:** AI, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$50.00 / 1,000 passage codeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Evidence-Quoted Text Coder — Bring Your Own Labels

Codes text against your own labels — and when it can't, it tells you *what* it can't, instead of guessing.

Give it a codebook (your labels, each with a few marker phrases) and some passages. For every passage it either returns **the label with the verbatim quote that earned it**, or it hands back **the named residual**: the two labels a passage fell between when the readings split, or an honest abstention where no quote held. That "I can't tell" isn't silence — it's a row you can read, and it's usually where your own labels overlap, which is the real finding a confidence number would have destroyed.

No AI calls. No training step. No model weights. No API keys. Nothing leaves the container.

### Why it's different

Most classifiers always answer — they hand you a label and a probability even when there's nothing there. This one is built the other way: each passage is read **two independent ways**, and a label is emitted only when both readings agree, nothing else competes for it, and the evidence is a **verbatim span** — not a vibe. When the readings disagree, it says so instead.

It needs no model and no training because everything it reads is what you handed it — your labels, their markers, your passages. Nothing is carried in from anywhere else, which is exactly why it cannot tell you anything your own evidence doesn't already carry. Run it twice on the same input and you get the same rows.

**Your markers are the gate.** A label's marker phrases are what can *refuse* it: a passage containing none of them is refused for that label, which is why every coded row can carry a quote. A label with no markers cannot be refused by its own words — it is admitted on agreement alone, so its rows carry a weaker guarantee than the rest. The run warns you which labels those are.

### Input

| Field | What it is |
|---|---|
| `codebook` | Your labels: `matching_modes → {dimension: {label: {lexical_markers: [...]}}}`. Optional `theme_definitions`. |
| `passages` | The text to code — strings, or `{text, source_url, source_title}`. |
| `datasetId` | Optionally pull passages from another Actor's dataset. |
| `question` | The question you're asking of this text. Stamped on every row, so an audit can be checked for whether it answers the question actually asked. |
| `exemplars` | Passages you've already confirmed, keyed `"dimension::label"`. Read as more of that label's evidence, so it sharpens. Nothing is stored between runs — they stay yours. |

### Output

**One row per passage per dimension — the codings and what could not be coded, side by side.**

```
{ "outcome": "coded",         "dimension": "...", "label": "...",   "evidence_quote": "<your passage>", ... }
{ "outcome": "fell_between",  "dimension": "...", "between": ["autonomy", "flexibility"], ... }
{ "outcome": "no_quote_held", "dimension": "...", "label_considered": "earnings", ... }
```

- **`coded`** — both readings agreed and the label's words are in the passage, which is quoted.
- **`fell_between`** — the two readings named different labels. Not a tie to be broken: usually it is where your own two labels overlap in this material, and it is the finding a confidence score would have hidden.
- **`no_quote_held`** — a label was reached for and not one of its words is in the passage, so it was refused.
- **`no_reading`** — nothing here to read.

Every row carries a `lens` tag (the labels-and-markers it was read through — unchanged when you add confirmed examples, so a session proves *same frame, more ground*), a `provenance` tag anyone can recompute, and a second independent `egress` tag from the outgoing door. `CODING_REPORT` in the key-value store holds the totals and `open_addresses` — which label pairs your passages kept falling between. A live **read-only window** shows the run's shape as it forms; counts and label-pair names pass the glass, never your text.

### Pricing

One meter, one price. You pay per **row** — and a residual row (`fell_between`, `no_quote_held`) costs *exactly the same* as a coded one, because the residual is half the deliverable, not a discount.

| Meter | When it fires | Price |
|---|---|---|
| **passage-coded** | Once per emitted row — a label with its verbatim quote, *or* the named residual | **$0.05 / row** ($50 / 1,000) |

**Count your rows before you run.** A passage is read once per dimension, and each reading is a row. Ten passages against a codebook with three dimensions is thirty rows, not ten — $1.50, not $0.50. That is the honest arithmetic and it is better to have it here than in an invoice.

Silence is free: an empty passage forms nothing and is never billed. There is no per-run fee and no subscription — this boots a standard-library process, and a startup charge would be a number nothing derived. You pay only for rows that formed, and never for a guess, because it never makes one.

#### How this price was derived

Priced by derivation, not by market-positioning. A careful human coding text *with evidence* runs $0.20–$1+ per item; this codes deterministically — with the verbatim quote and the honest abstention no probabilistic model can offer — at **$0.05/passage**, an **intro** rate well under the human labor it stands beside, normalizing toward the fair recovery rate over time. The competitors bill a subscription for a probability; you pay per formed row for a guarantee.

### The discipline

- **Fail-closed:** the coder proves its own contract before it reads a single passage.
- **Model-free:** pure standard library. No numpy, no ML runtime — you can list the container and see there is nothing in it to trust.
- **Yours:** the codebook is your meaning-structure. The engine never speaks meaning you didn't author; it only finds, or fails to find, your labels' evidence in the text.

# Actor input Schema

## `codebook` (type: `object`):

The labels to code against. Each dimension holds labels; each label lists the literal markers that are its governed evidence. Bring your own — this is your meaning-structure, not ours.

## `passages` (type: `array`):

The text items to code. Each item is a string, or an object with a `text` field (plus optional `source_url`, `source_title`).

## `datasetId` (type: `string`):

Pull passages from another Actor's dataset instead of (or in addition to) the inline list.

## `textField` (type: `string`):

When reading from a dataset, the field that holds the passage text.

## `maxItems` (type: `integer`):

An upper bound on how many passages this run reads, so a large dataset cannot cost more than you intended. It stops early rather than sampling: the passages it did read are coded in full, and nothing is guessed about the ones it never reached.

## `question` (type: `string`):

Optional, and worth filling in. Every row is stamped with the question it was coded under, so an audit you hand to someone else can be checked for whether it answers the question actually asked. Coding the same passages under a different question is a different reading, not the same one seen twice.

## `exemplars` (type: `object`):

Passages you have already judged, keyed "dimension::label". They are read as more of the label's evidence, so a label sharpens as you feed it your own confirmed examples. Nothing is stored between runs — hand them in each time, and they stay yours.

## Actor input object example

```json
{
  "codebook": {
    "matching_modes": {
      "framing": {
        "autonomy": {
          "lexical_markers": [
            "be your own boss",
            "work when you want",
            "your own schedule"
          ]
        },
        "earnings": {
          "lexical_markers": [
            "earn",
            "make money",
            "cash out",
            "weekly pay"
          ]
        }
      }
    }
  },
  "passages": [
    "Drive with us and be your own boss — work when you want, no manager.",
    "Sign up today. It is a serious job with real responsibilities and a fixed roster.",
    "Earn extra cash on weekends — you set your own schedule."
  ],
  "textField": "text",
  "maxItems": 10000,
  "question": "How does this copy frame the work?"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "codebook": {
        "matching_modes": {
            "framing": {
                "autonomy": {
                    "lexical_markers": [
                        "be your own boss",
                        "work when you want",
                        "your own schedule"
                    ]
                },
                "earnings": {
                    "lexical_markers": [
                        "earn",
                        "make money",
                        "cash out",
                        "weekly pay"
                    ]
                }
            }
        }
    },
    "passages": [
        "Drive with us and be your own boss — work when you want, no manager.",
        "Sign up today. It is a serious job with real responsibilities and a fixed roster.",
        "Earn extra cash on weekends — you set your own schedule."
    ],
    "question": "How does this copy frame the work?"
};

// Run the Actor and wait for it to finish
const run = await client.actor("equ1n0x/evidence-quoted-text-coder").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "codebook": { "matching_modes": { "framing": {
                "autonomy": { "lexical_markers": [
                        "be your own boss",
                        "work when you want",
                        "your own schedule",
                    ] },
                "earnings": { "lexical_markers": [
                        "earn",
                        "make money",
                        "cash out",
                        "weekly pay",
                    ] },
            } } },
    "passages": [
        "Drive with us and be your own boss — work when you want, no manager.",
        "Sign up today. It is a serious job with real responsibilities and a fixed roster.",
        "Earn extra cash on weekends — you set your own schedule.",
    ],
    "question": "How does this copy frame the work?",
}

# Run the Actor and wait for it to finish
run = client.actor("equ1n0x/evidence-quoted-text-coder").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "codebook": {
    "matching_modes": {
      "framing": {
        "autonomy": {
          "lexical_markers": [
            "be your own boss",
            "work when you want",
            "your own schedule"
          ]
        },
        "earnings": {
          "lexical_markers": [
            "earn",
            "make money",
            "cash out",
            "weekly pay"
          ]
        }
      }
    }
  },
  "passages": [
    "Drive with us and be your own boss — work when you want, no manager.",
    "Sign up today. It is a serious job with real responsibilities and a fixed roster.",
    "Earn extra cash on weekends — you set your own schedule."
  ],
  "question": "How does this copy frame the work?"
}' |
apify call equ1n0x/evidence-quoted-text-coder --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,equ1n0x/evidence-quoted-text-coder"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Z7fe8S5F0zlM9f2Ip/builds/xdcEtSbTyEy9QYjyM/openapi.json
