Analyzing Apparent Fishing Effort for Trawlers in an EEZ
Identify trawlers fishing in an EEZ, retrieve their identity, then check their port visits and encounters.
This workflow combines the 4Wings API, the Vessels API, and the Events API to analyze apparent fishing effort for trawlers in an EEZ, identify the vessels involved, and check their event history.
Use Case: A Fisheries Enforcement Officer Monitoring Industrial Trawlers
Maria, a fisheries enforcement officer in Argentina, monitors industrial trawlers operating within Argentina's Exclusive Economic Zone (EEZ). Her role includes:
- ✅ Analyzing apparent fishing effort for trawlers operating in Argentina's EEZ.
- ✅ Identifying vessels involved in apparent trawling activity and determining their reported flag states.
- ✅ Checking vessel history, including potential transshipment and port visits.
- ✅ Generating reports to support fisheries enforcement decisions.
To achieve this, Maria will use four Global Fishing Watch APIs:
- 4Wings API — Retrieve apparent fishing effort for trawlers.
- 4Wings API — Group vessels by ID that are involved in trawling activity.
- Vessels API — Retrieve vessel identity & ownership details.
- Events API — Fetch port visits & potential transshipment history.
Step 0: Identify the Region of Interest (ROI) — Argentina EEZ
Before making API requests, Maria must specify the geographic area for analysis using a Region ID:
Options to define the region:
- Using Region ID — Each EEZ has a unique ID in the
public-eez-areasdataset. - Custom Geometries — Users can define a custom area using GeoJSON.
- Find EEZ Region IDs using the Regions dataset — see the Datasets documentation.
- For Argentina's EEZ, the region ID is 8466 (
public-eez-areasdataset).
The 4Wings Report API provides flexible output formats, including TIFF (GeoTIFF) for geospatial mapping, JSON for raw data analysis, and CSV.
Important Caveats
- 🚨 The 4Wings API only supports one active report per user at a time.
- 🔴 Sending multiple requests simultaneously results in a 429 Too Many Requests error.
- Report Generation Time & Timeout Risks:
- If a report takes over 100 seconds to generate, it may return a 524 Gateway Timeout error.
- To retrieve a previously requested report, use the last-report endpoint instead. For details, see the 4Wings API documentation.
Step 1: Retrieve Apparent Fishing Effort in Argentina's EEZ
API Used: 4Wings API — /v3/4wings/report
Filters applied:
- Region ID = Argentina EEZ
- Date Range = Last 6 months
- Grouped by Gear Type
Why this step?
- ✅ Identifies which gear types (e.g., trawlers, squid jiggers) are most active in the EEZ.
- ✅ Establishes baseline fishing activity trends before narrowing the search to specific vessels.
API Request: POST
# Make sure to replace [TOKEN] with your API Access Token.
curl --location --globoff 'https://gateway.api.globalfishingwatch.org/v3/4wings/report?spatial-resolution=HIGH&temporal-resolution=MONTHLY&group-by=GEARTYPE&datasets[0]=public-global-fishing-effort%3Alatest&date-range=2024-08-01%2C2025-01-31&format=JSON' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [TOKEN]' \
--data '{
"region": {
"dataset": "public-eez-areas",
"id": 8466
}
}'result = await gfw_client.fourwings.create_report(
datasets=["public-global-fishing-effort:latest"],
spatial_resolution="HIGH",
temporal_resolution="MONTHLY",
group_by="GEARTYPE",
start_date="2024-08-01",
end_date="2025-01-31",
region={"dataset": "public-eez-areas", "id": 8466},
)gfw_ais_fishing_hours(
spatial_resolution = "HIGH",
temporal_resolution = "MONTHLY",
start_date = "2024-08-01",
end_date = "2025-01-31",
region_source = "EEZ",
region = 8466,
group_by = "GEARTYPE"
)// Make sure to replace [TOKEN] with your API Access Token.
const res = await fetch(
'https://gateway.api.globalfishingwatch.org/v3/4wings/report?spatial-resolution=HIGH&temporal-resolution=MONTHLY&group-by=GEARTYPE&datasets[0]=public-global-fishing-effort%3Alatest&date-range=2024-08-01%2C2025-01-31&format=JSON',
{
method: 'POST',
headers: {
Authorization: 'Bearer [TOKEN]',
'Content-Type': 'application/json',
},
body: JSON.stringify({
region: {
dataset: 'public-eez-areas',
id: 8466,
},
}),
}
)
const data = await res.json()What we've learned from Step 1
- Multiple gear types were potentially detected in Argentina's EEZ.
- Trawlers appear to be operating, but further vessel-level investigation is needed.
Example API Response:
{
"entries": [
{
"public-global-fishing-effort:v3.0": [
{
"date": "2024-09",
"geartype": "trawlers",
"hours": 1.1805555555555551,
"lat": -46.14,
"lon": -63.09,
"vesselIDs": 1
},
{
"date": "2025-01",
"geartype": "squid_jigger",
"hours": 1.978333333333333,
"lat": -46.69,
"lon": -62.83,
"vesselIDs": 1
}
]
}
]
}Step 2: Get Vessel IDs for Trawlers
Maria refines her 4Wings API request to group by VESSEL_ID, filtering specifically for trawlers.
Why this step?
- Links apparent fishing activity to specific vessels.
- Allows further verification using vessel identity records in Step 3.
Endpoint: /v3/4wings/report
Filters used:
- Region ID = Argentina EEZ
- Gear Type = Trawlers
- Grouped by Vessel ID
API Request: POST
# Make sure to replace [TOKEN] with your API Access Token.
curl --location --globoff 'https://gateway.api.globalfishingwatch.org/v3/4wings/report?spatial-resolution=LOW&temporal-resolution=ENTIRE&group-by=VESSEL_ID&datasets[0]=public-global-fishing-effort%3Alatest&date-range=2024-08-01%2C2025-01-31&format=JSON&filters[0]=geartype%20in%20(%27trawlers%27)' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [TOKEN]' \
--data '{
"region": {
"dataset": "public-eez-areas",
"id": 8466
}
}'result = await gfw_client.fourwings.create_report(
datasets=["public-global-fishing-effort:latest"],
spatial_resolution="LOW",
temporal_resolution="ENTIRE",
group_by="VESSEL_ID",
start_date="2024-08-01",
end_date="2025-01-31",
filters=["geartype in ('trawlers')"],
region={"dataset": "public-eez-areas", "id": 8466},
)gfw_ais_fishing_hours(
spatial_resolution = "LOW",
temporal_resolution = "ENTIRE",
start_date = "2024-08-01",
end_date = "2025-01-31",
region_source = "EEZ",
region = 8466,
group_by = "VESSEL_ID",
filter_by = "geartype in ('trawlers')"
)// Make sure to replace [TOKEN] with your API Access Token.
const res = await fetch(
'https://gateway.api.globalfishingwatch.org/v3/4wings/report?spatial-resolution=LOW&temporal-resolution=ENTIRE&group-by=VESSEL_ID&datasets[0]=public-global-fishing-effort%3Alatest&date-range=2024-08-01%2C2025-01-31&format=JSON&filters[0]=geartype%20in%20(%27trawlers%27)',
{
method: 'POST',
headers: {
Authorization: 'Bearer [TOKEN]',
'Content-Type': 'application/json',
},
body: JSON.stringify({
region: {
dataset: 'public-eez-areas',
id: 8466,
},
}),
}
)
const data = await res.json()Example API Response:
{
"entries": [
{
"public-global-fishing-effort:v3.0": [
{
"callsign": "LW 2962",
"dataset": "public-global-vessel-identity:v3.0",
"date": "2024-08-01,2025-01-31",
"entryTimestamp": "2024-08-01T03:00:00Z",
"exitTimestamp": "2024-09-29T10:00:00Z",
"firstTransmissionDate": "2017-04-10T15:34:43Z",
"flag": "ARG",
"geartype": "TRAWLERS",
"hours": 5.009722222222223,
"imo": "7728572",
"lastTransmissionDate": "2025-02-10T23:55:58Z",
"lat": -43.4,
"lon": -62,
"mmsi": "701000619",
"shipName": "MEVIMAR",
"vesselId": "f38fb1980-0be3-d9d5-b166-877d9e9f3dc6",
"vesselType": "FISHING"
}
]
}
]
}Explanation of Parameters:
temporal-resolution=ENTIRE— Aggregates data by the full period selected.group-by=GEARTYPE— Groups data by fishing gear type. For more information about vessel types and gear types, see the Datasets documentation.
Data source & considerations
The values returned in this response are primarily derived from Automatic Identification System (AIS) self-reported data.
- Self-Reported Information: The vessel name, MMSI, and flag are broadcast by the vessel's AIS transponder and may not always reflect official registry data. Some vessels may report incorrect or outdated information, either mistakenly or deliberately.
- Gear Type Classification Caveats: Gear type (e.g., Trawlers) is often inferred based on vessel behavior, registries, and historical data rather than explicitly transmitted via AIS. Some vessels may switch gear types or misreport their actual fishing methods.
Step 3: Retrieve Vessel Details
Maria queries the Vessel API to get identity & ownership details.
Endpoint: /v3/vessels/{vessel_id}
Filters used:
- Vessel ID from 4Wings API
- Dataset =
public-global-vessel-identity:latest - Includes =
POTENTIAL_RELATED_SELF_REPORTED_INFO— Vessels may change identifiers over time, such as their MMSI, IMO number, call sign, or even their name. This parameter helps users group all vessel ids that are potentially related as part of the same physical vessel based on publicly available registry information.
IMPORTANT: To avoid any misinterpretation of Global Fishing Watch data, please refer to our data caveats for Apparent Fishing Effort, Region source, Vessel ID, and Vessel identity data.
API Request: GET
# Make sure to replace [TOKEN] with your API Access Token.
curl --location --globoff 'https://gateway.api.globalfishingwatch.org/v3/vessels?datasets[0]=public-global-vessel-identity%3Alatest&ids[0]=f38fb1980-0be3-d9d5-b166-877d9e9f3dc6&includes[0]=POTENTIAL_RELATED_SELF_REPORTED_INFO' \
--header 'Authorization: Bearer [TOKEN]'result = await gfw_client.vessels.get_vessels_by_ids(
ids=["f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"],
datasets=["public-global-vessel-identity:latest"],
includes=["POTENTIAL_RELATED_SELF_REPORTED_INFO"],
)gfw_vessel_info(
search_type = "id",
ids = c("f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"),
includes = "POTENTIAL_RELATED_SELF_REPORTED_INFO"
)// Make sure to replace [TOKEN] with your API Access Token.
const res = await fetch(
'https://gateway.api.globalfishingwatch.org/v3/vessels?datasets[0]=public-global-vessel-identity%3Alatest&ids[0]=f38fb1980-0be3-d9d5-b166-877d9e9f3dc6&includes[0]=POTENTIAL_RELATED_SELF_REPORTED_INFO',
{ headers: { Authorization: 'Bearer [TOKEN]' } }
)
const data = await res.json()Example API Response:
{
"entries": [
{
"registryInfoTotalRecords": 1,
"registryInfo": [
{
"id": "c6b11037f6fa71be1862907471021d01",
"sourceCode": ["IMO"],
"ssvid": "701000619",
"flag": "ARG",
"shipname": "MEVIMAR",
"nShipname": "MEVIMAR",
"callsign": "LW2962",
"imo": "7728572",
"latestVesselInfo": true,
"transmissionDateFrom": "2013-03-08T22:19:15Z",
"transmissionDateTo": "2025-01-31T23:45:06Z",
"geartypes": ["FISHING"],
"lengthM": 37.5,
"tonnageGt": 221,
"vesselInfoReference": "3a6e31ef3bbf3036720b796c614d7c15",
"extraFields": []
}
],
"registryOwners": [
{
"name": "RIMINIMARR",
"flag": "ARG",
"ssvid": "701000619",
"sourceCode": ["IMO"],
"dateFrom": "2013-03-08T22:19:15Z",
"dateTo": "2025-01-31T23:45:06Z"
}
],
"registryPublicAuthorizations": [],
"combinedSourcesInfo": [
{
"vesselId": "f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"
}
]
}
]
}What we've learned from Step 3: Maria now has official records to cross-check against self-reported AIS data.
Understanding the response objects
- registryInfoTotalRecords — The number of registry records found for the vessels.
- registryInfo — Contains public registry data, sourced from official vessel registries.
- registryOwners — Lists the registered owners of the vessel based on public sources.
- registryPublicAuthorizations — Represents known fishing authorizations from public sources. Users should verify against national registries and RFMO records for additional context.
- combinedSourcesInfo — Provides inferred data from multiple sources, determined through GFW's classification methods.
- selfReportedInfo — Contains AIS self-reported data, including MMSI, ship name, and flag as broadcast by the vessel itself. Self-reported data may not always align with registry data and should be cross-checked.
Step 4: Detect Potential Port Visits, Encounters, or Fishing Events
Maria checks port visits, encounters, and fishing events using the Events API, which allows monitoring of vessel activities such as potential transshipments, unauthorized port entries, or fishing activity patterns.
Endpoint: /v3/events
Filters used:
- Vessel ID from 4Wings API
- Event Types = PORT_VISIT, ENCOUNTER, FISHING. To obtain other event types, please visit the Events API documentation.
- Datasets:
public-global-port-visits-events:latest(Port Visits)public-global-encounters-events:latest(Encounters between vessels)public-global-fishing-events:latest(Fishing activity)
API Request: GET
# Make sure to replace [TOKEN] with your API Access Token.
curl --location --globoff 'https://gateway.api.globalfishingwatch.org/v3/events?vessels[0]=f38fb1980-0be3-d9d5-b166-877d9e9f3dc6&encounter-types[0]=CARRIER-FISHING&sort=-start&start-date=2024-08-01&end-date=2025-01-31&limit=200&offset=0&datasets[0]=public-global-encounters-events%3Alatest&datasets[1]=public-global-fishing-events%3Alatest&datasets[2]=public-global-port-visits-events%3Alatest&include-regions=false&types[0]=ENCOUNTER&types[1]=FISHING&types[2]=PORT_VISIT' \
--header 'Authorization: Bearer [TOKEN]'result = await gfw_client.events.get_all_events(
datasets=[
"public-global-encounters-events:latest",
"public-global-fishing-events:latest",
"public-global-port-visits-events:latest",
],
vessels=["f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"],
types=["ENCOUNTER", "FISHING", "PORT_VISIT"],
encounter_types=["CARRIER-FISHING"],
start_date="2024-08-01",
end_date="2025-01-31",
sort="-start",
limit=200,
offset=0,
)gfw_event(
event_type = c("ENCOUNTER", "FISHING", "PORT_VISIT"),
vessels = "f38fb1980-0be3-d9d5-b166-877d9e9f3dc6",
encounter_types = "CARRIER-FISHING",
start_date = "2024-08-01",
end_date = "2025-01-31",
sort = "-start"
)// Make sure to replace [TOKEN] with your API Access Token.
const res = await fetch(
'https://gateway.api.globalfishingwatch.org/v3/events?vessels[0]=f38fb1980-0be3-d9d5-b166-877d9e9f3dc6&encounter-types[0]=CARRIER-FISHING&sort=-start&start-date=2024-08-01&end-date=2025-01-31&limit=200&offset=0&datasets[0]=public-global-encounters-events%3Alatest&datasets[1]=public-global-fishing-events%3Alatest&datasets[2]=public-global-port-visits-events%3Alatest&include-regions=false&types[0]=ENCOUNTER&types[1]=FISHING&types[2]=PORT_VISIT',
{ headers: { Authorization: 'Bearer [TOKEN]' } }
)
const data = await res.json()Example API Response:
{
"metadata": {
"datasets": [
"public-global-encounters-events:v3.0",
"public-global-fishing-events:v3.0",
"public-global-port-visits-events:v3.1"
],
"vessels": ["f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"],
"dateRange": {
"from": "2024-08-01",
"to": "2025-01-31"
},
"encounterTypes": ["CARRIER-FISHING"]
},
"limit": 200,
"offset": 0,
"nextOffset": null,
"total": 94,
"entries": [
{
"start": "2024-08-22T10:31:36.000Z",
"end": "2024-08-22T14:15:01.000Z",
"id": "aae842479c882c3122ad3655c790ad0d",
"type": "fishing",
"position": {
"lat": -43.216,
"lon": -62.3137
},
"distances": {
"startDistanceFromShoreKm": 124,
"endDistanceFromShoreKm": 115,
"startDistanceFromPortKm": 225.135859,
"endDistanceFromPortKm": 220.055141
},
"vessel": {
"id": "f38fb1980-0be3-d9d5-b166-877d9e9f3dc6",
"name": "MEVIMAR",
"ssvid": "701000619",
"flag": "ARG",
"type": "fishing",
"publicAuthorizations": [
{ "hasPubliclyListedAuthorization": "false", "rfmo": "ICCAT" },
{ "hasPubliclyListedAuthorization": "false", "rfmo": "CCSBT" }
]
},
"fishing": {
"totalDistanceKm": 24.478457436190546,
"averageSpeedKnots": 3.721428578453404,
"averageDurationHours": null,
"potentialRisk": false,
"vesselPublicAuthorizationStatus": "not_matching_relevant_public_authorization"
}
}
// ... additional events follow the same structure
]
}Response objects
- metadata — contains the datasets, vessel(s) queried, analysis period, and encounterTypes (e.g., CARRIER-FISHING).
- publicAuthorizations — showing whether the vessel has publicly listed authorizations.
- Activity-Specific Data — fishing, port visit, and encounter events (if present).
What we've learned from Step 4
- ✅ Apparent Fishing Events: The vessel "MEVIMAR" has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025).
- ✅ Port Visit Events: The vessel potentially made multiple port visits, including stops at Puerto Madryn, Buenos Aires, and Zarate. The confidence level for these visits is 4 (which may indicate high certainty but will need verification). Ports are based on the Global Fishing Watch anchorages dataset.
- ✅ No explicit ENCOUNTER events were returned in the response dataset.
IMPORTANT: Data Interpretation Caveats
- High confidence (level = 4) indicates that the vessel was identified using AIS with an entry, stop or gap, and exit within a port. A port visit with lower confidence may sometimes be a false port visit caused by noisy AIS transmission and requires a further inspection of the vessel tracks.
Potential Considerations:
- The vessel's fishing activities appear near the EEZ boundary, requiring further assessment of compliance with national or RFMO regulations.
- The absence of matching public authorizations in the RFMO registry does not necessarily indicate illegality, but it suggests that authorities may need to verify through national databases or official sources.
Summary of the API Flow
- 4Wings API → Retrieve apparent fishing effort for trawlers within Argentina's EEZ.
- Vessels API → Fetch vessel identity, ownership history, and public authorizations.
- Events API → Detect potential port visits, encounters, and apparent fishing events to analyze operational patterns.
- Assess potential risks → Compare registry records, AIS data, and inferred vessel activity for enforcement follow-ups.
- Generate a report → Provide a structured analysis for relevant authorities.
Analyzing Apparent Fishing Effort in a Region and Retrieving Vessel Details
Query apparent fishing effort for a region with the 4Wings Report API, then resolve the vessels behind it with the Vessels API.
Analyzing a Fleet (a Group of Vessels)
Combine the 4Wings, Vessels and Events APIs to analyze a fleet of vessels across fishing effort, identity and event history.