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

# WebExtrator uppgiftsfråge-API integrationsguide

> WebExtrator Web Render & Extract API guide - Ace Data Cloud

`POST https://api.acedata.cloud/webextrator/tasks`

WebExtrator uppgiftsfråge-API används för att fråga historiska `render` / `extract` uppgiftsresultat. Vanliga användningsområden:

* **Återfråga** det kompletta kuvertet efter att den asynkrona uppgiften har slutförts (förutom `callback_url` push eller aktiv polling).
* **Granska** vad man själv har skickat in - uppgiftsregister lagrar både den ursprungliga `request` och det slutliga `response`.
* **Batchåterfyllning** - hämta flera poster åt gången baserat på `id` eller `trace_id`.

Uppgiftsregister behålls i Redis i **7 dagar**.

Uppgiftsfrågegränssnittet är **gratis** (räknas inte in i Credits-användning).

## Auktorisering

```
Authorization: Bearer YOUR_API_KEY
Content-Type:  application/json
```

Man kan endast se uppgifter under sitt eget AceDataCloud-konto.

## Begärningsparametrar

Begärningskroppen är en diskriminant som delas in efter `action`, med två typer av åtgärder:

### `action: "retrieve"` —— Enstaka fråga

| Fält       | Typ    | Obligatoriskt | Beskrivning                                                            |
| ---------- | ------ | :-----------: | ---------------------------------------------------------------------- |
| `action`   | const  |       ✅       | Fast `"retrieve"` .                                                    |
| `id`       | string |    valfritt   | Uppgiftens ID (finns i varje render/extract kuvertets `task_id` fält). |
| `trace_id` | string |    valfritt   | Anropskedje-ID (kuvertets `trace_id` fält).                            |

`id` och `trace_id` ska skickas in som valfritt.

### `action: "retrieve_batch"` —— Batchfråga

| Fält        | Typ       | Obligatoriskt | Beskrivning                      |
| ----------- | --------- | :-----------: | -------------------------------- |
| `action`    | const     |       ✅       | Fast `"retrieve_batch"` .        |
| `ids`       | string\[] |    valfritt   | Lista över uppgifts-ID.          |
| `trace_ids` | string\[] |    valfritt   | Lista över anropskedje-ID.       |
| `offset`    | number    |       ❌       | Sidoffset (standard 0).          |
| `limit`     | number    |       ❌       | Sidstorlek, 1–100 (standard 50). |

`ids` och `trace_ids` ska skickas in som valfritt.

## Enstaka svar

```json theme={null}
{
  "task": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "trace_id": "550e8400-e29b-41d4-a716-446655440001",
    "type": "extract",
    "created_at": 1777717800.05,
    "started_at": 1777717800.123,
    "finished_at": 1777717802.535,
    "elapsed": 2.412,
    "request": {
      "url": "https://en.wikipedia.org/wiki/Diffbot",
      "expected_type": "article"
    },
    "response": {
      "success": true,
      "data": { /* Komplett extract kuvert */ }
    }
  }
}
```

Om ingen uppgift hittas returneras `{ "task": null }` (HTTP 200, inte 404).

Tidsfälten i `task`-objektet förklaras nedan.

* `created_at`, tidpunkt för uppgiftens skapande, Unix-tidsstämpel (sekunder, flyttal).
* `started_at`, tidpunkt för när uppgiften började köras, Unix-tidsstämpel (sekunder, flyttal). Om uppgiften inte har påbörjats är det `null`.
* `finished_at`, tidpunkt för när uppgiften slutfördes, Unix-tidsstämpel (sekunder, flyttal). Om uppgiften inte är slutförd är det `null`.
* `elapsed`, tid som uppgiften tog att utföra, i sekunder (flyttal, med 3 decimaler). Om uppgiften inte är slutförd är det `null`.

## Batchsvar

```json theme={null}
{
  "tasks": [
    { /* Samma struktur som enstaka .task */ },
    { /* ... */ }
  ],
  "offset": 0,
  "limit":  50
}
```

Icke-existerande ID:n kommer inte att ge fel, de kommer bara att saknas i `tasks`.

## Exempel

### Fråga enstaka post efter task\_id

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/tasks \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "retrieve",
    "id": "550e8400-e29b-41d4-a716-446655440000"
  }'
```

### Fråga enstaka post efter trace\_id

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/tasks \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "retrieve",
    "trace_id": "550e8400-e29b-41d4-a716-446655440001"
  }'
```

### Batchfråga

```bash theme={null}
curl -X POST https://api.acedata.cloud/webextrator/tasks \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "retrieve_batch",
    "ids": [
      "550e8400-e29b-41d4-a716-446655440000",
      "550e8400-e29b-41d4-a716-446655440002"
    ],
    "limit": 50
  }'
```

### Python (requests) —— Polling tills slutförd

```python theme={null}
import os, time, requests

API_KEY = os.environ["ACEDATA_API_KEY"]
BASE = "https://api.acedata.cloud"

# 1) Skicka in asynkron extraktion
queue = requests.post(
    f"{BASE}/webextrator/extract",
    headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
    json={"url": "https://example.com", "mode": "async"},
).json()

job_id = queue["jobId"]

# 2) Använd Tasks API för att pollinga tills uppgiften är slutförd
while True:
    r = requests.post(
        f"{BASE}/webextrator/tasks",
        headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
        json={"action": "retrieve", "id": job_id},
    ).json()
    task = r.get("task")
    if task and task.get("finished_at"):
        print("Tid", task["elapsed"], "sekunder")
        print(task["response"]["data"]["title"])
        break
    time.sleep(2)
```

### Node.js (fetch) —— Hämta komplett kuvert efter att ha fått callback

```js theme={null}
// I din callback_url hanteringsfunktion:
app.post('/hooks/webextrator', async (req, res) => {
  res.status(200).end();              // Snabbt ack

  const taskId = req.body?.task_id;
  if (!taskId) return;

  const fetchRes = await fetch('https://api.acedata.cloud/webextrator/tasks', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.ACEDATA_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ action: 'retrieve', id: taskId }),
  });
  const { task } = await fetchRes.json();
  console.log('Komplett kuvert:', task.response.data);
});
```

## Fel svar

| HTTP | `error.code`   | Betydelse                                                                         |
| ---- | -------------- | --------------------------------------------------------------------------------- |
| 400  | `bad_request`  | Validering misslyckades (saknar `action`, skickar både `id` och `trace_id` etc.). |
| 401  | `unauthorized` | Saknad eller ogiltig `Authorization: Bearer …` .                                  |

```json theme={null}
{ "error": { "code": "bad_request", "message": "..." } }
```

## Tips och fallgropar

* **Kan anpassa `trace_id`, gör det.** Vid den ursprungliga render/extract begäran ladda upp
  `?trace_id=…` (QueryString), synkronisera det med ditt eget affärs-ID (arbetsflöde run id osv.),
  därefter kan du använda affärs-ID för att söka efter uppgifter. Om det inte skickas genererar servern automatiskt en UUID.
* **Bevarandeperiod 7 dagar.** Tidigare uppgifter returnerar `task: null` — för långsiktig arkivering, vänligen spara i egen databas.
* **Uppgiftsfrågor är gratis.** Vill du fråga hur många gånger som helst, den ursprungliga render/extract anropet har redan betalats för.
* **Prioritera asynkront + callback, istället för polling.** Om affären tillåter, skicka
  `callback_url` i den ursprungliga begäran, så att plattformen kan skicka envelope till dig, vilket är mer effektivt än att pollera var 2:a sekund.
