> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retab.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Consensus

> Reconcile several objects into one.

Takes a list of `inputs` that describe the same thing — typically the outputs of
repeated extractions — and returns a single `consensus` object plus a `likelihoods`
map giving the agreement score for every leaf path.

Inputs are always aligned before the vote, so items in a list are matched across
inputs by content rather than by position; a reordered or partially-omitted array
still reconciles correctly. Supply `json_schema` when you have one: it makes numeric
fields reconcile by declared type — `integer` votes on the exact value, `number`
clusters and averages — instead of inferring the kind from the values present. Set
`include_alignment` to also receive the canonical path mapping.

Reconcile several objects that describe the same thing — typically the outputs of repeated extractions over one document — into a single `consensus` object, with a `likelihoods` map giving the agreement score for every leaf path. Low-likelihood paths are the ones worth routing to review.

Inputs are always aligned before the vote, so items in a list are matched across inputs by content rather than by position: a reordered or partially omitted array still reconciles correctly. Supply `json_schema` whenever you have one — it makes numeric fields reconcile by declared type (`integer` votes on the exact value, `number` clusters and averages) instead of inferring the kind from whichever values happen to be present.

<RequestExample>
  ```python Python theme={null}
  from retab import Retab

  client = Retab()

  # Three extraction runs over the same invoice
  inputs = [
      {"vendor": "Acme Corp", "total": 100.0},
      {"vendor": "Acme Corp", "total": 100.0},
      {"vendor": "Acme Corporation", "total": 102.0},
  ]

  schema = {
      "type": "object",
      "properties": {
          "vendor": {"type": "string"},
          "total": {"type": "number"},
      },
  }

  result = client.consensus.create(inputs=inputs, json_schema=schema)

  print(result.consensus)
  for field in result.fields:
      print(f"{field.path}: {field.value} ({field.likelihood:.2f})")
  ```

  ```typescript TypeScript theme={null}
  import { Retab } from "@retab/node";

  const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

  const inputs = [
    { vendor: "Acme Corp", total: 100.0 },
    { vendor: "Acme Corp", total: 100.0 },
    { vendor: "Acme Corporation", total: 102.0 },
  ];

  const schema = {
    type: "object",
    properties: {
      vendor: { type: "string" },
      total: { type: "number" },
    },
  };

  const result = await client.consensus.create(inputs, undefined, schema);

  console.log(result.consensus);
  result.fields.forEach((field) => {
    console.log(`${field.path}: ${field.value} (${field.likelihood})`);
  });
  ```

  ```go Go theme={null}
  package main

  import (
  	"context"
  	"fmt"
  	"log"

  	retab "github.com/retab-dev/retab/clients/go"
  )

  func main() {
  	ctx := context.Background()

  	client, err := retab.NewClient("")
  	if err != nil {
  		log.Fatal(err)
  	}

  	inputs := []map[string]interface{}{
  		{"vendor": "Acme Corp", "total": 100.0},
  		{"vendor": "Acme Corp", "total": 100.0},
  		{"vendor": "Acme Corporation", "total": 102.0},
  	}
  	schema := map[string]interface{}{
  		"type": "object",
  		"properties": map[string]interface{}{
  			"vendor": map[string]interface{}{"type": "string"},
  			"total":  map[string]interface{}{"type": "number"},
  		},
  	}

  	result, err := client.Consensus.Create(ctx, &retab.ConsensusCreateParams{
  		Inputs:     inputs,
  		JSONSchema: &schema,
  	})
  	if err != nil {
  		log.Fatal(err)
  	}

  	fmt.Printf("Consensus: %v\n", result.Consensus)
  	for _, field := range result.Fields {
  		fmt.Printf("%s: %v (%.2f)\n", field.Path, field.Value, field.Likelihood)
  	}
  }
  ```

  ```ruby Ruby theme={null}
  require 'retab'

  client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

  inputs = [
    { 'vendor' => 'Acme Corp', 'total' => 100.0 },
    { 'vendor' => 'Acme Corp', 'total' => 100.0 },
    { 'vendor' => 'Acme Corporation', 'total' => 102.0 },
  ]

  schema = {
    'type' => 'object',
    'properties' => {
      'vendor' => { 'type' => 'string' },
      'total' => { 'type' => 'number' },
    },
  }

  result = client.consensus.create(inputs: inputs, json_schema: schema)

  puts result.consensus
  result.fields.each do |field|
    puts "#{field.path}: #{field.value} (#{field.likelihood})"
  end
  ```

  ```rust Rust theme={null}
  use retab::models::CreateConsensusRequest;
  use retab::resources::consensus::CreateParams;
  use retab::Retab;
  use std::collections::HashMap;

  fn object(value: serde_json::Value) -> HashMap<String, serde_json::Value> {
      value
          .as_object()
          .expect("object")
          .iter()
          .map(|(k, v)| (k.clone(), v.clone()))
          .collect()
  }

  #[tokio::main]
  async fn main() -> Result<(), Box<dyn std::error::Error>> {
      let client = Retab::new(std::env::var("RETAB_API_KEY")?);

      let body = CreateConsensusRequest {
          inputs: Some(vec![
              object(serde_json::json!({"vendor": "Acme Corp", "total": 100.0})),
              object(serde_json::json!({"vendor": "Acme Corporation", "total": 102.0})),
          ]),
          json_schema: Some(object(serde_json::json!({
              "type": "object",
              "properties": {"vendor": {"type": "string"}, "total": {"type": "number"}}
          }))),
          ..Default::default()
      };

      let result = client.consensus().create(CreateParams::new(body)).await?;

      println!("{:?}", result.consensus);
      Ok(())
  }
  ```

  ```php PHP theme={null}
  <?php
  require 'vendor/autoload.php';

  use Retab\Client;

  $client = new Client(apiKey: getenv('RETAB_API_KEY'));

  $inputs = [
      ['vendor' => 'Acme Corp', 'total' => 100.0],
      ['vendor' => 'Acme Corp', 'total' => 100.0],
      ['vendor' => 'Acme Corporation', 'total' => 102.0],
  ];

  $schema = [
      'type' => 'object',
      'properties' => [
          'vendor' => ['type' => 'string'],
          'total' => ['type' => 'number'],
      ],
  ];

  $result = $client->consensus()->create($inputs, null, $schema);
  print_r($result);
  ```

  ```csharp C# theme={null}
  using Retab;
  using RetabClient = Retab.Retab;

  var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
  var client = new RetabClient(apiKey);

  var result = await client.Consensus.CreateAsync(new ConsensusCreateOptions
  {
      Inputs = new List<Dictionary<string, object>>
      {
          new() { ["vendor"] = "Acme Corp", ["total"] = 100.0 },
          new() { ["vendor"] = "Acme Corporation", ["total"] = 102.0 },
      },
      JsonSchema = new Dictionary<string, object>
      {
          ["type"] = "object",
      },
  });
  Console.WriteLine(result);
  ```

  ```java Java theme={null}
  import com.retab.RetabClient;
  import java.util.List;
  import java.util.Map;

  public final class Example {
    public static void main(String[] args) throws Exception {
      RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

      List<Map<String, Object>> inputs =
          List.of(
              Map.of("vendor", "Acme Corp", "total", 100.0),
              Map.of("vendor", "Acme Corporation", "total", 102.0));

      var result = client.consensus().create(null, inputs, Map.of("type", "object"));
      System.out.println(result);
    }
  }
  ```

  ```curl cURL theme={null}
  curl -X POST \
    'https://api.retab.com/v1/consensus' \
    -H "Authorization: Bearer $RETAB_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
    "inputs": [
      {"vendor": "Acme Corp", "total": 100.0},
      {"vendor": "Acme Corp", "total": 100.0},
      {"vendor": "Acme Corporation", "total": 102.0}
    ],
    "json_schema": {
      "type": "object",
      "properties": {
        "vendor": {"type": "string"},
        "total": {"type": "number"}
      }
    }
  }'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "consensus": {
      "vendor": "Acme Corp",
      "total": 100.67
    },
    "likelihoods": {
      "vendor": 0.6667,
      "total": 1.0
    },
    "fields": [
      {
        "path": "total",
        "value": 100.67,
        "likelihood": 1.0,
        "supporting_input_count": 0,
        "total_input_count": 3
      },
      {
        "path": "vendor",
        "value": "Acme Corp",
        "likelihood": 0.6667,
        "supporting_input_count": 2,
        "total_input_count": 3
      }
    ],
    "alignment": null
  }
  ```
</ResponseExample>


## OpenAPI

````yaml POST /v1/consensus
openapi: 3.1.0
info:
  title: FastAPI
  version: 0.1.0
servers:
  - url: https://api.retab.com
security: []
paths:
  /v1/consensus:
    post:
      tags:
        - consensus
      summary: Create Consensus
      description: >-
        Reconcile several objects into one.


        Takes a list of `inputs` that describe the same thing — typically the
        outputs of

        repeated extractions — and returns a single `consensus` object plus a
        `likelihoods`

        map giving the agreement score for every leaf path.


        Inputs are always aligned before the vote, so items in a list are
        matched across

        inputs by content rather than by position; a reordered or
        partially-omitted array

        still reconciles correctly. Supply `json_schema` when you have one: it
        makes numeric

        fields reconcile by declared type — `integer` votes on the exact value,
        `number`

        clusters and averages — instead of inferring the kind from the values
        present. Set

        `include_alignment` to also receive the canonical path mapping.
      operationId: create_consensus
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateConsensusRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReconciliationResult'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - HTTPBearer: []
components:
  schemas:
    CreateConsensusRequest:
      properties:
        include_alignment:
          type: boolean
          title: Include Alignment
        inputs:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          title: Inputs
        json_schema:
          additionalProperties: true
          type: object
          title: Json Schema
          default: {}
      additionalProperties: false
      type: object
      required:
        - inputs
      title: CreateConsensusRequest
    ReconciliationResult:
      properties:
        alignment:
          $ref: '#/components/schemas/ReconciliationAlignment'
        consensus:
          additionalProperties: true
          type: object
          title: Consensus
        fields:
          anyOf:
            - items:
                $ref: '#/components/schemas/ReconciliationField'
              type: array
            - type: 'null'
          title: Fields
        likelihoods:
          additionalProperties:
            type: number
          type: object
          title: Likelihoods
      type: object
      required:
        - alignment
        - consensus
        - fields
        - likelihoods
      title: ReconciliationResult
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
          default: []
      type: object
      title: HTTPValidationError
    ReconciliationAlignment:
      properties:
        aligned_inputs:
          anyOf:
            - items:
                additionalProperties: true
                type: object
              type: array
            - type: 'null'
          title: Aligned Inputs
        path_alignments:
          anyOf:
            - items:
                $ref: '#/components/schemas/ReconciliationPathAlignment'
              type: array
            - type: 'null'
          title: Path Alignments
        reference_index:
          type: integer
          title: Reference Index
      type: object
      required:
        - aligned_inputs
        - path_alignments
        - reference_index
      title: ReconciliationAlignment
    ReconciliationField:
      properties:
        likelihood:
          type: number
          title: Likelihood
        path:
          type: string
          title: Path
        supporting_input_count:
          type: integer
          title: Supporting Input Count
        total_input_count:
          type: integer
          title: Total Input Count
        value:
          title: Value
      type: object
      required:
        - likelihood
        - path
        - supporting_input_count
        - total_input_count
        - value
      title: ReconciliationField
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
          default: null
        ctx:
          type: object
          title: Context
          default: {}
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    ReconciliationPathAlignment:
      properties:
        canonical_path:
          type: string
          title: Canonical Path
        source_paths:
          anyOf:
            - items:
                anyOf:
                  - type: string
                  - type: 'null'
              type: array
            - type: 'null'
          title: Source Paths
      type: object
      required:
        - canonical_path
        - source_paths
      title: ReconciliationPathAlignment
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````