# Turn a text with Label value lines into named fields

`POST /v1/find/string/fields`

Reads system emails and forms such as 'Name: X' and 'Order: Y' into an object of label to value. Give the labels to look for (a label that is not found is null, never an error) or leave them out to detect every 'Label: value' line. The separator, multi-line values, trimming and case are options, and HTML (for example an Outlook body) can be converted to text first. The first occurrence of a repeated label wins.

## Request body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| text | string | yes | The text, plain or HTML |
| labels | array of string | no | The labels to look for. Leave out to detect every 'Label: value' line |
| separator | string | no | Between the label and the value: for example :, - or a tab (default `":"`) |
| multiline | boolean | no | A value continues on the following lines until the next label (default `false`) |
| trim | boolean | no | Remove spaces around values (default `true`) |
| ignore_case | boolean | no | Match labels whatever their case (default `true`) |
| html | boolean | no | The text is HTML (for example an Outlook body): convert it to text first (default `false`) |

## Example request

A request body that works, as JSON.

```json
{
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}
```

## Code samples

Replace YOUR_TOKEN with your access token.

### curl

```shell
curl -X POST 'https://api.skillfulsardine.com/v1/find/string/fields' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}'
```

### PowerShell

```powershell
$body = @'
{
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}
'@
$response = Invoke-RestMethod -Method Post -Uri 'https://api.skillfulsardine.com/v1/find/string/fields' `
  -Headers @{ Authorization = 'Bearer YOUR_TOKEN' } `
  -ContentType 'application/json; charset=utf-8' `
  -Body ([System.Text.Encoding]::UTF8.GetBytes($body))
$response | ConvertTo-Json -Depth 10
```

### Python

```python
import requests

payload = {
    "text": "From: maria@example.com\nSubject: Invoice 42",
    "multiline": True,
}

response = requests.post(
    "https://api.skillfulsardine.com/v1/find/string/fields",
    headers={"Authorization": "Bearer YOUR_TOKEN"},
    json=payload,
    timeout=30,
)
print(response.json())
```

### JavaScript

```javascript
const response = await fetch("https://api.skillfulsardine.com/v1/find/string/fields", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}),
});
const result = await response.json();
console.log(result);
```

### Node

```javascript
// 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/find/string/fields", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}),
});
const result = await response.json();
console.log(result);
```

### Rust

```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#"{
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}"#)?;
    let response = reqwest::blocking::Client::new()
        .post("https://api.skillfulsardine.com/v1/find/string/fields")
        .bearer_auth("YOUR_TOKEN")
        .json(&body)
        .send()?;
    println!("{}", response.text()?);
    Ok(())
}
```

### Swift

```swift
import Foundation

var request = URLRequest(url: URL(string: "https://api.skillfulsardine.com/v1/find/string/fields")!)
request.httpMethod = "POST"
request.setValue("Bearer YOUR_TOKEN", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = Data(#"""
{
  "text": "From: maria@example.com\nSubject: Invoice 42",
  "multiline": true
}
"""#.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 |
| --- | --- | --- | --- |
| fields | object | yes | Label to value. A label that was asked for and not found is null. The first occurrence wins |
| found | array of string | yes | The labels that were found, in the order they appear in the text |

## Example response

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

```json
{
  "data": {
    "fields": {
      "From": "maria@example.com",
      "Subject": "Invoice 42"
    },
    "found": [
      "From",
      "Subject"
    ]
  },
  "errors": null,
  "meta": {
    "request_id": "eba9d8f4-a6a1-4945-8ff6-c9aaffca1e20",
    "timestamp": "2026-10-27T07:19:42.123325Z",
    "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 |

---
Source: https://skillfulsardine.com/developers/api/extract-fields/