# Euroopahanked Agent API Guide

This guide is for AI agents and tools that use Euroopahanked.ee on behalf of an authenticated customer. The Agent API is read-only and is meant for finding relevant tenders, reviewing selected tender details, asking supported document-based tender questions, checking previous contract awards, and showing billing status.

Do not use this API for mass downloading, database copying or reselling Euroopahanked data. The API is intended to help the customer's own agent find relevant opportunities and review selected details. If information obtained through Euroopahanked is published or quoted outside the service, include a clear reference to Euroopahanked.ee.

## Base Information

- Base URL: `https://euroopahanked.ee`
- API prefix: `/api/agent/v1`
- Authentication: browser-confirmed device flow, then `Authorization: Bearer <agent_token>`
- Default language: English
- Estonian language: add `lang=et`
- Response format: JSON
- Machine-readable capabilities: `/api/agent/v1/capabilities`
- Public auth/discovery guide: `/auth.md`
- Protected resource metadata: `/.well-known/oauth-protected-resource`
- MCP JSON-RPC endpoint: `/mcp`

Agents should normally create a token with the browser-confirmed device flow. A logged-in Euroopahanked user can also create a token manually in the company profile integrations view. Token validity is normally up to 30 days, but never beyond the company's active service period.

## Create A Token With Device Flow

Start a connection request:

```http
POST /api/agent/v1/device/start
Content-Type: application/json
```

Body:

```json
{
  "clientName": "Codex"
}
```

Example response:

```json
{
  "deviceCode": "ehad_...",
  "userCode": "ABCD-1234",
  "verificationUrl": "https://euroopahanked.ee/liidestused/uhenda",
  "verificationUrlComplete": "https://euroopahanked.ee/liidestused/uhenda?code=ABCD-1234",
  "expiresAt": "2026-08-11T12:15:00",
  "intervalSeconds": 5
}
```

Show `verificationUrlComplete` to the user. The user must open it in a browser, log in if needed, and approve access for the active company. If the user does not yet have an account, they can register from the same browser flow; after successful authentication or registration, Euroopahanked returns them to the agent connection approval page.

Poll for the token:

```http
POST /api/agent/v1/device/token
Content-Type: application/json
```

Body:

```json
{
  "deviceCode": "ehad_..."
}
```

While the user has not approved access, the response contains:

```json
{
  "status": "pending",
  "error": "authorization_pending",
  "message": "User confirmation is pending"
}
```

After approval, the response contains:

```json
{
  "status": "approved",
  "accessToken": "ehag_...",
  "tokenType": "Bearer",
  "expiresAt": "2026-09-10T23:59:59",
  "companyId": "8f6343c4-6cd5-4c45-bf30-ed070182a8a5"
}
```

Poll no more often than `intervalSeconds`. Never log or expose `deviceCode` or `accessToken` to the end user beyond the connection flow.

## Core Rules For Agents

1. Start with `GET /api/agent/v1/me` to verify access, company status and limits.
2. Tender search must include at least `keyword` or `cpv`.
3. Contract search must include at least `cpv`, `buyer` or `winner`.
4. Do not request details for every search result. Request details only when the user wants to inspect a specific tender or contract.
5. Use the returned `id` value when opening a selected tender or contract detail. Treat it as an API reference for this token, not as a public identifier.
6. If `documentQuestionsSupported` is `true`, use the document-question endpoint for document-based follow-up questions.
7. Do not try to download tender documents through this API. The document-question endpoint returns an answer, not document files.
8. If you receive `429`, explain that the daily or monthly detail limit is reached.
9. If you receive `402` or `403`, direct the user to account or billing settings.

## Health Check

```http
GET /api/agent/v1/health
```

Example response:

```json
{
  "enabled": true
}
```

## Capabilities

```http
GET /api/agent/v1/capabilities
```

This endpoint is public and machine-readable. Use it to discover the supported Agent API endpoints, authentication mode, languages and current detail limits before making authenticated calls.

## MCP JSON-RPC

MCP-style clients can use the same read-only tools through:

```http
POST /mcp
Authorization: Bearer <token>
Content-Type: application/json
```

Supported methods:

- `initialize`
- `tools/list`
- `tools/call`

The `tools/call` method supports:

- `list_cpvs`
- `search_tenders`
- `get_tender`
- `ask_tender_documents`
- `search_contracts`
- `get_contract`
- `get_billing_status`

The MCP endpoint uses the same service-status checks, audit log and detail limits as the REST API.

## Account And Limits

```http
GET /api/agent/v1/me
Authorization: Bearer <token>
```

Example response:

```json
{
  "companyId": "8f6343c4-6cd5-4c45-bf30-ed070182a8a5",
  "companyName": "Example OÜ",
  "displayName": "Agent token",
  "expiresAt": "2026-09-10T23:59:59",
  "tenderDetailDailyLimit": 50,
  "tenderDetailMonthlyLimit": 1000,
  "contractDetailDailyLimit": 50,
  "contractDetailMonthlyLimit": 1000
}
```

## Find CPV Codes

If the user does not know the exact CPV code, discover available sectors or codes first:

```http
GET /api/agent/v1/cpv?level=2&limit=50
Authorization: Bearer <token>
```

Search by code or label:

```http
GET /api/agent/v1/cpv?q=software&level=8&limit=20&lang=en
Authorization: Bearer <token>
```

Important fields:

- `code`: CPV code or prefix according to the requested `level`.
- `prefix`: two-digit CPV sector.
- `label`: CPV label in the selected language.
- `tenderCount`: number of published tenders in this CPV group.
- `openTenderCount`: number of open tenders in this CPV group.

The CPV list is based on published Euroopahanked tenders and does not expose tender detail references.

## Search Tenders

Search by keyword:

```http
GET /api/agent/v1/tenders?keyword=software&country=LVA&page=1&pageSize=10
Authorization: Bearer <token>
```

Search by CPV:

```http
GET /api/agent/v1/tenders?cpv=72200000&lang=et&page=1&pageSize=10
Authorization: Bearer <token>
```

Important fields:

- `id`: API reference for opening this tender detail with the current token.
- `title`, `summary`: localized user-facing tender text.
- `buyer`
- `countryCode`, `countryName`
- `cpvCode`, `cpvLabel`
- `deadline`
- `status`
- `estimatedValue`, `estimatedCurrency`
- `documentsAvailable`: the source has an official document path or portal reference.
- `documentQuestionsSupported`: the agent can ask controlled document-based questions.
- `documentAccessMode`: document capability mode.

Possible `documentAccessMode` values:

- `DOCUMENT_QUESTIONS_SUPPORTED`: Euroopahanked can use the official tender documents in a controlled question-answer workflow.
- `OFFICIAL_PORTAL_ONLY`: documents or extra details are available in the official portal, but document-based Agent API questions are not supported.
- `UNKNOWN`: document capability is not known.

## Tender Detail

```http
GET /api/agent/v1/tenders/{agentTenderUuid}?lang=et
Authorization: Bearer <token>
```

This may use the company's tender detail quota. Use it only for tenders that the user actually wants to inspect.

The response can include the real external tender ID, official links, summary, requirements, document capability fields and related metadata.

## Document-Based Tender Question

Use this endpoint only when a search or detail response contains:

```json
{
  "documentQuestionsSupported": true,
  "documentAccessMode": "DOCUMENT_QUESTIONS_SUPPORTED"
}
```

Request:

```http
POST /api/agent/v1/tenders/{agentTenderUuid}/document-question
Authorization: Bearer <token>
Content-Type: application/json
```

Body:

```json
{
  "question": "What are the technical requirements and what evidence must the bidder provide?",
  "language": "en"
}
```

Example response:

```json
{
  "answer": "Based on the tender documents ...",
  "sourceNote": "documents",
  "documentQuestionsSupported": true,
  "documentAccessMode": "DOCUMENT_QUESTIONS_SUPPORTED"
}
```

Possible `sourceNote` values:

- `documents`: official tender documents were used.
- `stored`: only stored tender data was used.

If document questions are not supported for the tender, the endpoint returns `400`.

## Search Contracts

Contract search must include at least one meaningful filter: `cpv`, `buyer` or `winner`.

```http
GET /api/agent/v1/contracts?cpv=72200000&country=LVA&page=1&pageSize=10
Authorization: Bearer <token>
```

The search result includes an `id` only when the contract detail can be opened by the agent.

## Contract Detail

```http
GET /api/agent/v1/contracts/{agentContractUuid}?lang=et
Authorization: Bearer <token>
```

The detail response may include the related tender external ID and official source URL if they are available and verified.

## Billing Status

```http
GET /api/agent/v1/billing/status
Authorization: Bearer <token>
```

Use this when the user asks about service validity, invoice status or invoice download links.

## Typical Workflow

1. Call `GET /me`.
2. If service is active, search tenders by CPV or keyword.
3. Show 3-10 relevant results to the user.
4. Request tender detail only for a user-selected tender.
5. If `documentQuestionsSupported = true` and the user asks about requirements or technical specifications, use the document-question endpoint.
6. If the user asks about market prices or previous winners, search contracts by CPV, buyer or winner.

## Error Codes

- `400`: incomplete request or document question not supported.
- `401`: missing or invalid token.
- `402`: service access is not active.
- `403`: company or user is not allowed to use the requested resource.
- `404`: the selected tender or contract reference expired or does not belong to this token.
- `429`: daily or monthly detail limit reached.

## Security Requirements

- Do not expose the token to the end user after setup.
- Do not log the token.
- Do not crawl or mirror the full database.
- Do not resell data obtained through Euroopahanked.
- If Euroopahanked data is published or quoted outside the service, include a clear reference to Euroopahanked.ee.
- Do not share tender or contract detail references with other users or companies. They are token-scoped.
