Documentation

Getting started

mrickwood.cz monitors public procurement tenders across the EU. You can use it through the web dashboard, or integrate via REST API.

Web usage

Get started in the dashboard

Nothing to install or code. A browser and an email are enough.

1. Create an account

Go to /register and fill in your email, name and optionally a Czech company ID (IČO). If you provide IČO, the company name, VAT and address are auto-filled from the ARES registry.

Don't enter a password yet — you'll set it in the next step after clicking the verification link.

2. Verify the email and set a password

Within a few seconds you'll get an email with a verification link. Click it. You'll land on a page where you set your password (min. 8 characters).

Once the password is set you're logged in and can go straight to the dashboard.

3. Create your first tender filter

In the dashboard click Tenders → New filter. A filter is a saved set of criteria the system uses to send you matching tenders:

  1. Region — region or multiple regions (Prague, Central Bohemian, …)
  2. Industry — tender category (Buildings, IT development, …) or CPV code
  3. Keywords — words that must appear in the title or description (e.g. "bridge reconstruction")
  4. Value — min/max expected tender value

Detailed description of all filter parameters is in the Lead Watcher docs.

4. Enable the email digest

Every filter can have a daily email digest. Every day at 7:00 you get an email with tenders added that day matching your filter.

The digest is toggled in the filter detail — "Email digest" switch at the top. You can have multiple filters, each with its own digest setting.

API integration

REST API

If you want the data programmatically — e.g. to feed it into your ERP or CRM — use the REST API. All endpoints are under /api/v2, authentication via an API key. Most endpoints return JSON in an envelope with a single 'data' key; exceptions are invoice PDFs (binary), match export (CSV/XLSX unless you set format=json) and document preview (302 redirect to a signed URL).

Hello world

With a key the call looks like this:

curl -H "X-Api-Key: mrw_live_…" \
  "https://mrickwood.cz/api/v2/leads/tenders/search?qText=bridge%20reconstruction&limit=5"

Returns JSON with the latest open tenders. Full search parameters are in the Lead Watcher docs.

How to get a key

Your first API key is created via the dashboard: sign up on the web, verify your email, then in Settings → Integrations click "Generate key". The key is shown once — save it immediately (e.g. into env / secrets store). If you lose it, create a new one and delete the old.

Using the key with MCP clients (Claude Desktop, Cursor, …)

The key is the same as for REST API. Only how the client sends it differs: the MCP server runs at /api/mcp and the key goes into the X-Api-Key handshake header. Full setup for Claude Desktop, Cursor and generic HTTP clients is in the MCP docs.

Authentication

All /api/v2 endpoints authenticate with a single API key (format mrw_live_HEX64). The key can be sent as an X-Api-Key header or as a Bearer token:

# header X-Api-Key
curl -H "X-Api-Key: mrw_live_…" https://veritra.io/api/v2/account/me

# nebo Bearer (kompatibilní s OpenAPI client generators)
curl -H "Authorization: Bearer mrw_live_…" https://veritra.io/api/v2/account/me

The key carries the user identity. Which services it can call is decided by the subscription (see the Subscriptions section). You can have up to 5 active keys — useful to separate prod / dev / per-system.

Response envelope

All v2 endpoints return a unified JSON envelope. Single resource under data, paginated lists under data + pagination, errors under error.

Success

// Single resource
{ "data": { "id": "…", "field": "…" } }

// Paginated list
{
  "data": [{ "…": "…" }],
  "pagination": { "nextCursor": "abc123…", "totalCount": 42 }
}

Error

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Field 'url' must be a valid HTTPS URL.",
    "details": { "field": "url" }
  }
}

Stable error codes: UNAUTHORIZED, FORBIDDEN, NOT_FOUND, VALIDATION_ERROR, CONFLICT, RATE_LIMITED, ENTITLEMENT_REQUIRED, INTERNAL. Clients should branch on code, not on message — HTTP status maps to code automatically.

Rate limits

ParameterTypeDescription
Account API — read60/min, 5,000/dayGET on /api/v2/account/*
Account API — write10/min, 200/dayPOST, PUT, PATCH, DELETE
Service APIs100/h/keyMonthly quota depends on the service — see service docs

On overage the API returns HTTP 429 with a Retry-After header (seconds).

Trial and billing

After creating an account you get a 1-day free trial of Lead Watcher — no card, no billing profile needed. After that you need a card on file or a paid proforma invoice, otherwise the service moves to SUSPENDED and further calls return 403. No tier bundles — pay per service, cancel anytime.

Account API

Manage account, keys, billing and webhooks. All /api/v2/account/* endpoints require key authentication.

GET/api/v2/account/me

Equivalent to /profile + /subscriptions + apiKey info. Useful for the initial load in UI clients.

{
  "data": {
    "account": { "email": "…", "name": "…", "company": "…", "ico": "…", "country": "CZ", "locale": "cs", "isComplete": true },
    "subscriptions": [
      { "service": "LEADS", "scope": "CZ", "state": "ACTIVE", "tier": "PAID", "trialEndsAt": null, "paidUntil": "2026-06-30T22:00:00.000Z", "cancelAtPeriodEnd": false }
    ],
    "apiKey": { "keyPrefix": "mrw_live_7fa7785c", "lastUsedAt": "…", "requestsMonth": 120, "requestsLimit": 500 }
  }
}
GET/api/v2/account/profile
PATCH/api/v2/account/profile

Password and session

GET/api/v2/account/password
POST/api/v2/account/password
POST/api/v2/account/sessions/revoke

API keys

The key authenticates against the whole API. You can have up to 5 active keys. The raw key is returned only on creation or rotation — afterwards only retrievable by creating a new one.

GET/api/v2/account/keys
POST/api/v2/account/keys
{ "label": "Production ERP" }
{
  "data": {
    "id": "cm…",
    "key": "mrw_live_<hex64>",
    "keyPrefix": "mrw_live_7fa7785c",
    "label": "Production ERP",
    "createdAt": "…"
  }
}

The key in the response is in full only here. The server stores only the SHA-256 hash; the raw key can't be retrieved later. If lost, create a new one and delete the old.

GET/api/v2/account/keys/:id
PATCH/api/v2/account/keys/:id
DELETE/api/v2/account/keys/:id
POST/api/v2/account/keys/:id/rotate

Service subscriptions

Trial activation, state overview, scheduled cancellation at paidUntil/trialEndsAt. For paid card activation use /billing/checkout.

GET/api/v2/account/subscriptions
POST/api/v2/account/subscriptions
{ "service": "LEADS", "scope": "CZ", "mode": "trial" }
POST/api/v2/account/subscriptions/batch
{ "service": "LEADS", "scopes": ["CZ","SK","DE"], "mode": "trial" }
PATCH/api/v2/account/subscriptions/:service
{ "cancelAtPeriodEnd": true }

API usage

Daily aggregate of API key calls for the last N days (default 30). For monitoring rate limit consumption.

GET/api/v2/account/usage?days=30

Billing

GET/api/v2/account/billing
PATCH/api/v2/account/billing
POST/api/v2/account/billing/checkout
POST/api/v2/account/billing/customer-portal
POST/api/v2/account/billing/proforma
{ "cycle": "MONTHLY", "currency": "CZK", "scopes": ["CZ","SK"] }
GET/api/v2/account/billing/invoices
GET/api/v2/account/billing/invoices/:invoiceId

Data export (GDPR)

GET/api/v2/account/export
POST/api/v2/account/export

Account cancellation

POST/api/v2/account/cancel/request
{ "action": "DEACTIVATE" }
POST/api/v2/account/cancel/confirm

Webhooks

Account-level webhooks — one endpoint covers all filters and future services. Each event carries an HMAC-SHA256 signature in X-Signature-256, an idempotency key in X-Idempotency-Key and the type in X-Event-Type. Retry with exponential backoff up to ~33 h.

Max 5 endpoints per account. Supported events and payload schemas are documented per service.

GET/api/v2/account/webhooks
POST/api/v2/account/webhooks
{
  "url": "https://yourapp.cz/api/veritra-webhook",
  "enabledEvents": ["leads.match.created"],
  "description": "production"
}
GET/api/v2/account/webhooks/:id
PATCH/api/v2/account/webhooks/:id
DELETE/api/v2/account/webhooks/:id
POST/api/v2/account/webhooks/:id/rotate-secret

Notifications

GET/api/v2/account/notifications
PATCH/api/v2/account/notifications

Feedback

POST/api/v2/feedback

OpenAPI 3.1 spec

The full machine-readable API spec is at /openapi.json. Use it to auto-generate typed clients in any language (TypeScript, Python, Go, Rust, …) or to import into Postman / Insomnia / Swagger UI.

# Generate TypeScript client
npx openapi-typescript https://veritra.io/openapi.json -o ./mrickwood-types.ts

# Generate Python client (openapi-python-client)
openapi-python-client generate --url https://veritra.io/openapi.json

Error codes

CodeMeaning
400Missing field, invalid JSON, invalid format
401Missing X-Api-Key / Bearer, expired / invalid token
402No active subscription for the service
403Token does not belong to this account, or service is in beta without whitelist
404Key / token / endpoint not found
409Email already registered / key already exists / endpoint limit (5) / filter limit (20)
410Token or code expired or already used
412Email not verified — step 2 not yet completed
429Rate limit (Retry-After header)
500Server error