> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.etera.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.etera.dev/_mcp/server.

# SDKs & Code Examples

## Direct API Access

ETERA APIs are standard REST endpoints — use any HTTP client to integrate. All endpoints accept JSON and return JSON responses.

#### TypeScript

```typescript
const ETERA_BASE = "https://api.etera.dev";

async function eteraFetch(path: string, options: RequestInit = {}) {
  const res = await fetch(`${ETERA_BASE}${path}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${process.env.ETERA_TOKEN}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });

  if (!res.ok) {
    const error = await res.json();
    throw new Error(error.error?.message || `HTTP ${res.status}`);
  }

  return res.json();
}
```

#### Python

```python
import os
import requests

ETERA_BASE = "https://api.etera.dev"
TOKEN = os.environ["ETERA_TOKEN"]

def etera_fetch(path, method="GET", body=None):
    headers = {
        "Authorization": f"Bearer {TOKEN}",
        "Content-Type": "application/json",
    }
    res = requests.request(
        method, f"{ETERA_BASE}{path}",
        headers=headers, json=body
    )
    res.raise_for_status()
    return res.json()
```

#### cURL

```bash
# Set your token
export ETERA_TOKEN="your_jwt_token"

# Make requests
curl "https://api.etera.dev/restaurant/search/recommendations/" \
  -H "Authorization: Bearer $ETERA_TOKEN"
```

---

## Common Operations

#### Search Restaurants

**`TypeScript`**

```typescript title="TypeScript"
const restaurants = await eteraFetch(
  "/restaurant/search/recommendations/"
);
```

**`Python`**

```python title="Python"
restaurants = etera_fetch("/restaurant/search/recommendations/")
```

**`cURL`**

```bash title="cURL"
curl "https://api.etera.dev/restaurant/search/recommendations/" \
  -H "Authorization: Bearer $ETERA_TOKEN"
```

#### Search Hotels

**`TypeScript`**

```typescript title="TypeScript"
const hotels = await eteraFetch(
  "/hotel/search/v2/search?city=dubai&checkIn=2025-03-01&checkOut=2025-03-05"
);
```

**`Python`**

```python title="Python"
hotels = etera_fetch(
  "/hotel/search/v2/search?city=dubai&checkIn=2025-03-01&checkOut=2025-03-05"
)
```

**`cURL`**

```bash title="cURL"
curl "https://api.etera.dev/hotel/search/v2/search?city=dubai&checkIn=2025-03-01&checkOut=2025-03-05" \
  -H "Authorization: Bearer $ETERA_TOKEN"
```

#### Search Flights

**`TypeScript`**

```typescript title="TypeScript"
const flights = await eteraFetch(
  "/flight/search/search?from=DXB&to=LHR&date=2025-03-01"
);
```

**`Python`**

```python title="Python"
flights = etera_fetch(
  "/flight/search/search?from=DXB&to=LHR&date=2025-03-01"
)
```

**`cURL`**

```bash title="cURL"
curl "https://api.etera.dev/flight/search/search?from=DXB&to=LHR&date=2025-03-01" \
  -H "Authorization: Bearer $ETERA_TOKEN"
```

#### Create a Booking

**`TypeScript`**

```typescript title="TypeScript"
const booking = await eteraFetch("/restaurant/booking/bookings/", {
  method: "POST",
  body: JSON.stringify({
    restaurantId: "rest_123",
    date: "2025-03-01",
    time: "19:00",
    partySize: 4,
  }),
});
```

**`Python`**

```python title="Python"
booking = etera_fetch(
  "/restaurant/booking/bookings/",
  method="POST",
  body={
    "restaurantId": "rest_123",
    "date": "2025-03-01",
    "time": "19:00",
    "partySize": 4,
  }
)
```

**`cURL`**

```bash title="cURL"
curl -X POST "https://api.etera.dev/restaurant/booking/bookings/" \
  -H "Authorization: Bearer $ETERA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"restaurantId":"rest_123","date":"2025-03-01","time":"19:00","partySize":4}'
```

#### Use MCP Tools

**`TypeScript`**

```typescript title="TypeScript"
// List available tools
const tools = await eteraFetch("/restaurant/mcp/mcp/tools");

// Execute a tool
const result = await eteraFetch(
  "/restaurant/mcp/mcp/execute/search_restaurants",
  {
    method: "POST",
    body: JSON.stringify({ query: "Italian in Dubai Marina" }),
  }
);
```

**`Python`**

```python title="Python"
# List available tools
tools = etera_fetch("/restaurant/mcp/mcp/tools")

# Execute a tool
result = etera_fetch(
  "/restaurant/mcp/mcp/execute/search_restaurants",
  method="POST",
  body={"query": "Italian in Dubai Marina"}
)
```

#### AI Supervisor

**`TypeScript`**

```typescript title="TypeScript"
const conversation = await eteraFetch("/ai/input", {
  method: "POST",
  body: JSON.stringify({
    inputType: "text",
    text: "Find me a beachfront hotel in Dubai for next weekend",
    context: {
      location: { type: "pinned", city: "Dubai" },
    },
  }),
});

// Check status
const status = await eteraFetch(
  `/ai/status/${conversation.conversationId}`
);
```

**`Python`**

```python title="Python"
conversation = etera_fetch("/ai/input", method="POST", body={
    "inputType": "text",
    "text": "Find me a beachfront hotel in Dubai for next weekend",
    "context": {
        "location": {"type": "pinned", "city": "Dubai"},
    },
})

# Check status
status = etera_fetch(f"/ai/status/{conversation['conversationId']}")
```

---

## OpenAPI Specs & Code Generation

All ETERA services expose OpenAPI 3.0.3 specs for automated client generation.

| Vertical          | Spec URL                                                                                                             |
| ----------------- | -------------------------------------------------------------------------------------------------------------------- |
| Restaurant Search | [https://api-dev.etera.dev/restaurant/search/swagger/json](https://api-dev.etera.dev/restaurant/search/swagger/json) |
| Hotel Search      | [https://api-dev.etera.dev/hotel/search/swagger/json](https://api-dev.etera.dev/hotel/search/swagger/json)           |
| Flight Search     | [https://api-dev.etera.dev/flight/search/swagger/json](https://api-dev.etera.dev/flight/search/swagger/json)         |
| Experience Search | [https://api-dev.etera.dev/experience/search/swagger/json](https://api-dev.etera.dev/experience/search/swagger/json) |
| Auth              | [https://api-dev.etera.dev/auth/swagger/json](https://api-dev.etera.dev/auth/swagger/json)                           |

### Generate a TypeScript Client

#### Install the generator

```bash
npm install -D openapi-typescript
```

#### Generate types from a spec

```bash
npx openapi-typescript https://api-dev.etera.dev/restaurant/search/swagger/json \
  -o ./src/types/restaurant-search.ts
```

#### Use the generated types

```typescript
import type { paths } from "./types/restaurant-search";

type SearchResponse =
  paths["/recommendations/"]["get"]["responses"]["200"]["content"]["application/json"];
```

---

## Error Handling

**`TypeScript`**

```typescript title="TypeScript"
try {
  const data = await eteraFetch("/restaurant/search/recommendations/");
} catch (error) {
  if (error.message.includes("401")) {
    // Re-authenticate
  } else if (error.message.includes("429")) {
    // Rate limited — back off and retry
  } else {
    console.error("ETERA API error:", error.message);
  }
}
```

**`Python`**

```python title="Python"
from requests.exceptions import HTTPError

try:
    data = etera_fetch("/restaurant/search/recommendations/")
except HTTPError as e:
    if e.response.status_code == 401:
        # Re-authenticate
        pass
    elif e.response.status_code == 429:
        # Rate limited — back off and retry
        pass
    else:
        print(f"ETERA API error: {e}")
```

---

## Next Steps

#### [Getting Started](/guides/getting-started)

Make your first API call

#### [Authentication](/guides/authentication)

Set up JWT tokens

#### [MCP Integration](/guides/mcp-integration)

Connect AI models