Compare

Find what each array has that the other does not

POST/v1/compare/array/difference

View as Markdown

Returns the items only in the first array and the items only in the second array, each in its own first-seen order. Use it for "who has not submitted": the first array is who was expected, the second is who answered. Compare objects by one property or as a whole.

Request body

Name Type Required Description
key string no Compare objects by this property (a dotted path such as owner.id reaches into nested objects). Default: compare the items as a whole
ignore_case boolean no Treat text that differs only by upper and lower case as equal (default false)
trim boolean no Ignore spaces around text when comparing (default false)
first array of any yes The first array
second array of any yes The second array

Example request

A request body that works, as JSON.

{
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}

Code samples

Replace YOUR_TOKEN with your access token.

curl

curl -X POST 'https://api.skillfulsardine.com/v1/compare/array/difference' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}'

PowerShell

$body = @'
{
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}
'@
$response = Invoke-RestMethod -Method Post -Uri 'https://api.skillfulsardine.com/v1/compare/array/difference' `
  -Headers @{ Authorization = 'Bearer YOUR_TOKEN' } `
  -ContentType 'application/json; charset=utf-8' `
  -Body ([System.Text.Encoding]::UTF8.GetBytes($body))
$response | ConvertTo-Json -Depth 10

Python

import requests

payload = {
    "first": [
        "a@example.com",
        "b@example.com",
    ],
    "second": [
        "b@example.com",
        "c@example.com",
    ],
}

response = requests.post(
    "https://api.skillfulsardine.com/v1/compare/array/difference",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    json=payload,
    timeout=30,
)
print(response.json())

JavaScript

const response = await fetch("https://api.skillfulsardine.com/v1/compare/array/difference", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}),
});
const result = await response.json();
console.log(result);

Node

// Node 18 or later. Save as call.mjs and run: API_TOKEN=... node call.mjs
const token = process.env.API_TOKEN;

const response = await fetch("https://api.skillfulsardine.com/v1/compare/array/difference", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}),
});
const result = await response.json();
console.log(result);

Rust

// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }, serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let body: serde_json::Value = serde_json::from_str(r#"{
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}"#)?;
    let response = reqwest::blocking::Client::new()
        .post("https://api.skillfulsardine.com/v1/compare/array/difference")
        .bearer_auth("YOUR_TOKEN")
        .json(&body)
        .send()?;
    println!("{}", response.text()?);
    Ok(())
}

Swift

import Foundation

var request = URLRequest(url: URL(string: "https://api.skillfulsardine.com/v1/compare/array/difference")!)
request.httpMethod = "POST"
request.setValue("Bearer YOUR_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(#"""
{
  "first": [
    "a@example.com",
    "b@example.com"
  ],
  "second": [
    "b@example.com",
    "c@example.com"
  ]
}
"""#.utf8)

let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))

Response

The fields inside data of a successful response.

Name Type Required Description
only_in_first array of any yes Items of the first array that are not in the second
only_in_second array of any yes Items of the second array that are not in the first
only_in_first_count integer yes Number of items only in the first array
only_in_second_count integer yes Number of items only in the second array

Example response

A real answer from the operation, as JSON. The fields in the table above are inside data.

{
  "data": {
    "only_in_first": [
      "a@example.com"
    ],
    "only_in_second": [
      "c@example.com"
    ],
    "only_in_first_count": 1,
    "only_in_second_count": 1
  },
  "errors": null,
  "meta": {
    "request_id": "3f59c0a5-4817-414c-aeaa-acffa33953b4",
    "timestamp": "2026-10-27T07:19:42.110445Z",
    "version": "2026-03-26"
  },
  "pagination": null
}

Responses

Status When it happens
200 Successful Response
400 The body respects the operation schema, but the use case rejected it. Each problem is one ApiError entry
413 The request is larger than the request size limit of the API allows
422 The body does not respect the operation schema. Each problem is one ApiError entry with the code validation_error
500 Something failed inside the server and was not an input problem. The same envelope, errors may be empty