# Run your first extraction

Use `Makra.extract()` for the simplest complete workflow. Version 0.0.4 submits durable work, polls it to completion, and returns the complete response envelope. Your script does not need to manage deferred runs itself.

## Prerequisites

- Python 3.9 or newer
- The `makra` package installed with `pip install makra`
- A Makra API key in `MAKRA_API_KEY`, or passed to `Makra(api_key=...)`

`Makra()` reads `MAKRA_API_KEY` when you omit the constructor argument. The hosted API rejects the development placeholder key.

## Complete example

This request asks for two visible fields from one product page. The program succeeds when it prints the extracted object for that URL and exits 0.

```python
from makra import Makra

urls = ["https://shop.example/products/atlas-lamp"]
schema = {
    "name": "The main product name",
    "price": "The current selling price as displayed on the page",
}

with Makra() as client:
    response = client.extract(urls, schema)

if not isinstance(response, dict):
    raise RuntimeError("Expected a JSON object response")

if response.get("status") not in {"succeeded", "partial"}:
    raise RuntimeError(response.get("message", "Extraction failed"))

data = response.get("data", {})
product = data.get(urls[0])
print(product)
```

The shorthand schema maps field names to descriptions. Write descriptions that distinguish nearby concepts. "Current selling price" is more useful than "price" when the page also contains list price, savings, and shipping cost.

## What happens on the first call

`extract()` sends the request as a deferred run, keeps its run ID, polls the run, and downloads the stored result after completion. This avoids gateway timeouts during long extractions. If the client wait deadline expires, `MakraTimeoutError.run_id` identifies the durable run so you can retrieve it later with `get_run()`.

Makra renders the URL and checks whether stored knowledge covers its structure. For a new page class, it learns a broader description of what the page contains, binds fields to structural locations, stores those bindings, and executes the bindings needed by this request.

A later URL with the same page shape can reuse that knowledge. It is still rendered, and current values still come from that page.

## Use a JSON Schema when shape matters

The shorthand is good for small objects. Use the supported JSON Schema subset for nested objects, arrays, field descriptions, and explicit structure.

```python
schema = {
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "The main product name",
        },
        "price": {
            "type": "string",
            "description": "The current selling price as displayed",
        },
    },
    "required": ["name"],
}
```

Declared scalar types describe the requested schema. Extraction remains opaque. A value such as `"$129.00"` remains a string. Parse it after checking extraction quality and source context.

## A URL is not a browser script

The URL must be a public web URL accepted by Makra's admission rules. Do not pass localhost, an IP literal, embedded credentials, or a private-network address. Makra may normalize plain HTTP to HTTPS.

If the page needs a login or a custom interaction before data appears, this first call is not enough. The public SDK does not expose arbitrary browser actions.

Next, [read the full response correctly](/markdown/makra-sdk/v0.0.4-beta/getting-started/read-the-response).
