Fish Data API
OData v4 feeds for buyer agreements and auction lot prices captured from fish auctions.
The Fish Data API exposes fish-auction data as OData v4 feeds, making it easy to query, filter, and integrate data into tools like Power BI, Excel, or any OData-compatible client. Two collections are available:
BuyerAgreements — buyer and hammer-price agreements streamed live from the auction
as lots are sold. AuctionLots — the full daily lot catalogue scraped from the
auction sheet, with species, gear, seller, weight and the realised price per kilogram.
OData v4 over HTTPS
JSON (application/json)
API key via header or query param
1 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)
X-Api-Key: your-api-key-here
Option 2 — Query parameter
https://fish.metadata.is/odata/BuyerAgreements?api_key=your-api-key-here
Requests with a missing or invalid key receive a 401 Unauthorized response.
Base URL
https://fish.metadata.is/odata
The OData service root is /odata. All entity sets are relative to this path.
Endpoints
Two read-only collections are available. Both support the OData query options listed below.
List buyer agreements
Returns a collection of buyer agreements. Supports all OData query options listed below.
Get a single agreement
Returns a single buyer agreement by its integer Id.
List auction lots
Returns a collection of auction lots — one row per lot from the daily auction sheet.
Get a single lot
Returns a single auction lot by its integer Id.
Fields
Buyer Agreements
| Field | Type | Description |
|---|---|---|
Id |
Integer | Unique record identifier (auto-assigned). |
LotNumber |
String | The lot identifier from the auction (e.g. A-001). |
Buyer |
String | Name of the buyer as reported by the auction system. |
Price |
Decimal | Hammer price in ISK. |
AuctionDate |
Date | The auction trading day (YYYY-MM-DD). |
ReceivedAt |
DateTimeOffset | UTC timestamp when the agreement was captured. |
Auction Lots
| Field | Type | Description |
|---|---|---|
Id | Integer | Unique record identifier (auto-assigned). |
AuctionDate | Date | The auction trading day (YYYY-MM-DD). |
Species | String | Fish species (e.g. Þorskur — cod). |
SpeciesCondition | String | Condition the species group was sold under (e.g. Óslægt — ungutted). |
GroupTotalKg | Integer | Total kilograms offered in the species/condition group this lot belongs to. |
Lot | String | Lot identifier within the auction (e.g. 1-1). |
Gear | String | Fishing gear used (e.g. Lína — longline). |
Seller | String | Seller / vessel as reported by the auction. |
Condition | String | Lot condition grading. |
Size | String | Size grading of the fish. |
Age | String | Age / freshness of the catch (e.g. 1-dags — one day). |
Location | String | Auction market / landing location. |
WeightKg | Integer | Weight of this lot, in kilograms. |
PriceKrPerKg | Integer (nullable) | Realised price in ISK per kg. null until the auction has run. |
ScrapedAt | DateTimeOffset | UTC timestamp when the lot was scraped. |
PriceKrPerKg is only populated during and after the auction (around 17:00 Iceland time on weekdays). 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:
| Option | Description | Example |
|---|---|---|
$filter |
Filter rows by a boolean expression. | $filter=Buyer eq 'Jón Jónsson' |
$select |
Return only the specified fields. | $select=LotNumber,Price |
$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
| Operator | Meaning | Example |
|---|---|---|
eq | Equals | Buyer eq 'Jón Jónsson' |
ne | Not equals | Buyer ne 'Unknown' |
gt | Greater than | Price gt 500000 |
ge | Greater than or equal | Price ge 1000000 |
lt | Less than | Price lt 200000 |
le | Less than or equal | Price le 999999 |
and | Logical AND | Price gt 500000 and Buyer eq 'Jón' |
or | Logical OR | LotNumber eq 'A-001' or LotNumber eq 'B-002' |
Filtering
Filter by buyer name
GET /odata/BuyerAgreements?$filter=Buyer eq 'Jón Jónsson' X-Api-Key: your-api-key-here
Filter by lot number
GET /odata/BuyerAgreements?$filter=LotNumber eq 'A-042' X-Api-Key: your-api-key-here
Filter by date range
GET /odata/BuyerAgreements?$filter=ReceivedAt ge 2025-01-01T00:00:00Z and ReceivedAt lt 2025-02-01T00:00:00Z X-Api-Key: your-api-key-here
Filter by minimum price
GET /odata/BuyerAgreements?$filter=Price ge 1000000 X-Api-Key: your-api-key-here
Example response
{
"@odata.context": "https://fish.metadata.is/odata/$metadata#BuyerAgreements",
"value": [
{
"Id": 1,
"LotNumber": "A-042",
"Buyer": "Jón Jónsson",
"Price": 1250000.00,
"ReceivedAt":"2025-01-15T13:04:27Z"
}
]
}
Selecting Fields
Use $select to return only the fields you need, reducing payload size.
GET /odata/BuyerAgreements?$select=LotNumber,Buyer,Price X-Api-Key: your-api-key-here
{
"@odata.context": ".../$metadata#BuyerAgreements(LotNumber,Buyer,Price)",
"value": [
{ "LotNumber": "A-042", "Buyer": "Jón Jónsson", "Price": 1250000.00 }
]
}
Sorting & Paging
Top 10 most expensive lots
GET /odata/BuyerAgreements?$orderby=Price 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.
$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
GET /odata/BuyerAgreements?$orderby=Id&$count=true X-Api-Key: your-api-key-here
{
"@odata.context": "https://fish.metadata.is/odata/$metadata#BuyerAgreements",
"@odata.count": 3420,
"@odata.nextLink": "https://fish.metadata.is/odata/BuyerAgreements?$orderby=Id&$skip=1000",
"value": [ /* 1 000 records */ ]
}
Page 2 — follow nextLink or use $skip manually
GET /odata/BuyerAgreements?$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.
Agreements from a specific auction day, sorted by price
GET /odata/BuyerAgreements ?$filter=ReceivedAt ge 2025-05-15T00:00:00Z and ReceivedAt lt 2025-05-16T00:00:00Z &$orderby=Price desc &$select=LotNumber,Buyer,Price &$count=true X-Api-Key: your-api-key-here
High-value lots for a specific buyer
GET /odata/BuyerAgreements ?$filter=Buyer eq 'Jón Jónsson' and Price ge 500000 &$orderby=ReceivedAt desc &$top=100 X-Api-Key: your-api-key-here
Auction Lots
The AuctionLots collection works exactly like BuyerAgreements — the same
query options apply. 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
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)
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
GET /odata/AuctionLots?$select=AuctionDate,Species,Lot,WeightKg,PriceKrPerKg&$orderby=AuctionDate desc X-Api-Key: your-api-key-here
Example response
{
"@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
Use the built-in OData feed connector for the best experience — Power BI understands OData natively and can push query folding back to the server.
-
Open the OData feed connector
In Power BI Desktop: Get Data → OData feed. Paste a collection URL:
URLhttps://fish.metadata.is/odata/BuyerAgreements https://fish.metadata.is/odata/AuctionLots
Or point Power BI at the service root
https://fish.metadata.is/odataand pick either collection from the navigator. -
Add the API key header
Click Advanced, then under HTTP request header parameters add:
Header name Value X-Api-Keyyour-api-key-here -
Connect & load
Click OK → Connect. Power BI will load the schema and show a preview. Click Load or Transform Data to shape the data in Power Query.
-
Schedule refresh (optional)
After publishing to the Power BI Service, configure a gateway data source or use the cloud gateway. Re-add the
X-Api-Keyheader in the data source credentials under Advanced → HTTP request header parameters.
?api_key=your-key to the URL instead. See the Authentication section for details.