OData API
v1

Fish Data API

An OData v4 feed of auction lot prices captured from fish auctions.

The Fish Data API exposes fish-auction data as an OData v4 feed, making it easy to query, filter, and integrate data into tools like Power BI, Excel, or any OData-compatible client.

AuctionLots — the full daily lot catalogue scraped from the auction sheet, with species, gear, seller, weight, the realised price per kilogram, and the matched buyer.

Protocol

OData v4 over HTTPS

Format

JSON (application/json)

Auth

API key via header or query param

Max page size

5 000 rows per request

Authentication

Every request must include an API key. You can pass it either as an HTTP request header (recommended) or as a query parameter (useful for tools that cannot set custom headers, such as the Power BI Web connector).

Option 1 — HTTP header (recommended)

HTTP
X-Api-Key: your-api-key-here

Option 2 — Query parameter

URL
https://fish.metadata.is/odata/AuctionLots?api_key=your-api-key-here
⚠ Avoid embedding API keys in URLs that may be logged or shared. Prefer the header approach whenever possible.

Requests with a missing or invalid key receive a 401 Unauthorized response.

Base URL

URL
https://fish.metadata.is/odata

The OData service root is /odata. All entity sets are relative to this path.

Endpoints

One read-only collection is available, supporting all OData query options listed below.

List auction lots

GET /odata/AuctionLots

Returns a collection of auction lots — one row per lot from the daily auction sheet.

Get a single lot

GET /odata/AuctionLots(id)

Returns a single auction lot by its integer Id.

Fields

Auction Lots

Field Type Description
IdIntegerUnique record identifier (auto-assigned).
AuctionDateDateThe auction trading day (YYYY-MM-DD).
SpeciesStringFish species (e.g. Þorskur — cod).
SpeciesConditionStringCondition the species group was sold under (e.g. Óslægt — ungutted).
GroupTotalKgIntegerTotal kilograms offered in the species/condition group this lot belongs to.
LotStringLot identifier within the auction (e.g. 1-1).
GearStringFishing gear used (e.g. Lína — longline).
SellerStringSeller / vessel as reported by the auction.
ConditionStringLot condition grading.
SizeStringSize grading of the fish.
AgeStringAge / freshness of the catch (e.g. 1-dags — one day).
LocationStringAuction market / landing location.
WeightKgIntegerWeight of this lot, in kilograms.
PriceKrPerKgInteger (nullable)Realised price in ISK per kg. null until the auction has run.
BuyerString (nullable)Buyer matched from the auction's buyer agreements. null if no match could be resolved.
ScrapedAtDateTimeOffsetUTC timestamp when the lot was scraped.
⚠ PriceKrPerKg is only populated during and after the auction (around 17:00 Iceland time, Sunday to Friday). Lots fetched earlier in the day will have a null price.

Query Options

The following standard OData system query options are supported on both collections:

OptionDescriptionExample
$filter Filter rows by a boolean expression. $filter=Buyer eq 'Jón Jónsson'
$select Return only the specified fields. $select=Lot,PriceKrPerKg
$orderby Sort results. Append desc for descending. $orderby=Price desc
$top Limit number of rows returned (max 1 000). $top=100
$skip Skip the first N rows — use with $top to page through results. $skip=1000
$count Include total row count in the response. $count=true

Filter operators

OperatorMeaningExample
eqEqualsBuyer eq 'Jón Jónsson'
neNot equalsBuyer ne 'Unknown'
gtGreater thanPrice gt 500000
geGreater than or equalPrice ge 1000000
ltLess thanPrice lt 200000
leLess than or equalPrice le 999999
andLogical ANDPrice gt 500000 and Buyer eq 'Jón'
orLogical ORLot eq 'A-001' or Lot eq 'B-002'

Filtering

Filter by buyer name

HTTP
GET /odata/AuctionLots?$filter=Buyer eq 'Jón Jónsson'
X-Api-Key: your-api-key-here

Filter by lot number

HTTP
GET /odata/AuctionLots?$filter=Lot eq '1-1'
X-Api-Key: your-api-key-here

Filter by date range

HTTP
GET /odata/AuctionLots?$filter=AuctionDate ge 2025-01-01 and AuctionDate lt 2025-02-01
X-Api-Key: your-api-key-here

Filter by minimum price

HTTP
GET /odata/AuctionLots?$filter=PriceKrPerKg ge 1000
X-Api-Key: your-api-key-here

Example response

200 OK · application/json
JSON
{
  "@odata.context": "https://fish.metadata.is/odata/$metadata#AuctionLots",
  "value": [
    {
      "Id":           1,
      "AuctionDate":  "2025-01-15",
      "Lot":          "42-1",
      "Buyer":        "Jón Jónsson",
      "PriceKrPerKg": 1250
    }
  ]
}

Selecting Fields

Use $select to return only the fields you need, reducing payload size.

HTTP
GET /odata/AuctionLots?$select=Lot,Buyer,PriceKrPerKg
X-Api-Key: your-api-key-here
200 OK · application/json
JSON
{
  "@odata.context": ".../$metadata#AuctionLots(Lot,Buyer,PriceKrPerKg)",
  "value": [
    { "Lot": "42-1", "Buyer": "Jón Jónsson", "PriceKrPerKg": 1250 }
  ]
}

Sorting & Paging

Top 10 most expensive lots

HTTP
GET /odata/AuctionLots?$orderby=PriceKrPerKg desc&$top=10
X-Api-Key: your-api-key-here

Paging through large result sets

The API returns at most 1 000 rows per request. When more results exist the response includes an @odata.nextLink URL — follow it to fetch the next page. Use $count=true on the first request to know the total up front.

ℹ Always include $orderby when paging. Without it the database may return rows in a different order on each page, causing duplicates or gaps.

Page 1 — fetch first 1 000 rows and total count

HTTP
GET /odata/AuctionLots?$orderby=Id&$count=true
X-Api-Key: your-api-key-here
200 OK · application/json
JSON
{
  "@odata.context":  "https://fish.metadata.is/odata/$metadata#AuctionLots",
  "@odata.count":   3420,
  "@odata.nextLink": "https://fish.metadata.is/odata/AuctionLots?$orderby=Id&$skip=1000",
  "value": [ /* 1 000 records */ ]
}

Page 2 — follow nextLink or use $skip manually

HTTP
GET /odata/AuctionLots?$orderby=Id&$skip=1000
X-Api-Key: your-api-key-here

Continue incrementing $skip by 1 000 until the response contains no @odata.nextLink — that means you have reached the last page.

Combined Queries

Query options can be combined freely in a single request.

Lots from a specific auction day, sorted by price

HTTP
GET /odata/AuctionLots
  ?$filter=AuctionDate eq 2025-05-15
  &$orderby=PriceKrPerKg desc
  &$select=Lot,Buyer,PriceKrPerKg
  &$count=true
X-Api-Key: your-api-key-here

High-value lots for a specific buyer

HTTP
GET /odata/AuctionLots
  ?$filter=Buyer eq 'Jón Jónsson' and PriceKrPerKg ge 500
  &$orderby=AuctionDate desc
  &$top=100
X-Api-Key: your-api-key-here

More Auction Lots Examples

A few more common queries against AuctionLots. Note that AuctionDate is a pure date, so filter it without quotes or a time component (e.g. AuctionDate eq 2026-06-05).

All cod lots on a given auction day

HTTP
GET /odata/AuctionLots?$filter=Species eq 'Þorskur' and AuctionDate eq 2026-06-05
X-Api-Key: your-api-key-here

Highest price-per-kg lots (priced lots only)

HTTP
GET /odata/AuctionLots?$filter=PriceKrPerKg ne null&$orderby=PriceKrPerKg desc&$top=10
X-Api-Key: your-api-key-here

Select just the columns you need

HTTP
GET /odata/AuctionLots?$select=AuctionDate,Species,Lot,WeightKg,PriceKrPerKg&$orderby=AuctionDate desc
X-Api-Key: your-api-key-here

Example response

200 OK · application/json
JSON
{
  "@odata.context": "https://fish.metadata.is/odata/$metadata#AuctionLots",
  "value": [
    {
      "Id":               1,
      "AuctionDate":      "2026-06-05",
      "Species":          "Þorskur",
      "SpeciesCondition": "Óslægt",
      "GroupTotalKg":     6451,
      "Lot":              "1-1",
      "Gear":             "Lína",
      "Seller":           "2755 - Jón Ásbjörnsson RE-777",
      "Condition":        "Ó",
      "Size":             "Bl.Umál",
      "Age":              "1-dags",
      "Location":         "FMÍS / Þorl",
      "WeightKg":         12,
      "PriceKrPerKg":     null,
      "ScrapedAt":        "2026-06-07T14:36:33Z"
    }
  ]
}

Power BI Integration

Connect using the Web connector rather than the OData feed connector — it gives reliable control over the X-Api-Key request header, which the OData feed connector's Advanced options don't consistently apply.

ℹ The Web connector returns the raw OData JSON response instead of a fully-typed navigation table, so you'll expand the value array into columns after connecting. It also doesn't support query folding — apply $filter, $select, $orderby, and $top directly in the URL instead. See Query Options for the syntax.
  1. Open the Web connector

    In Power BI Desktop: Get Data → Web. Choose Advanced so you can add a request header, and enter the URL:

    URL
    https://fish.metadata.is/odata/AuctionLots
  2. Add the API key header

    In the same Advanced panel, under HTTP request header parameters add:

    Header nameValue
    X-Api-Keyyour-api-key-here
  3. Shape the JSON into a table

    Click OK. Power BI opens Power Query with the raw JSON response. Click into the value list, then To Table, then use the expand button on the resulting column to break the records out into fields.

  4. Connect & load

    Once the columns look right, click Close & Apply (or Load).

  5. Schedule refresh (optional)

    After publishing to the Power BI Service, set the data source credentials for this Web source to Anonymous, then re-add the X-Api-Key header under Edit credentials → Advanced → HTTP request header parameters. Use a literal header value rather than one built from other query steps — Power BI's privacy/firewall checks can otherwise block scheduled refresh.

ℹ If your Power BI environment cannot send custom headers at all, append ?api_key=your-key to the URL instead. See the Authentication section for details.