# Analyzing Apparent Fishing Effort for Trawlers in an EEZ (/docs/api-workflows/monitoring-trawlers-in-an-eez)



This workflow combines the [4Wings API](/docs/v3/4wings), the [Vessels API](/docs/v3/vessels), and the [Events API](/docs/v3/events) 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 [#use-case-a-fisheries-enforcement-officer-monitoring-industrial-trawlers]

Maria, a fisheries enforcement officer in **Argentina**, monitors industrial trawlers operating within Argentina's &#x2A;*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](/docs/v3/4wings)** — Retrieve apparent fishing effort for trawlers.
* **[4Wings API](/docs/v3/4wings)** — Group vessels by ID that are involved in trawling activity.
* **[Vessels API](/docs/v3/vessels)** — Retrieve vessel identity & ownership details.
* **[Events API](/docs/v3/events)** — Fetch port visits & potential transshipment history.

## Step 0: Identify the Region of Interest (ROI) — Argentina EEZ [#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-areas` dataset.
* **Custom Geometries** — Users can define a custom area using GeoJSON.
* **Find EEZ Region IDs** using the Regions dataset — see the [Datasets documentation](/docs/v3/datasets).
* For Argentina's EEZ, the region ID is **8466** (`public-eez-areas` dataset).

The **4Wings Report API** provides flexible output formats, including &#x2A;*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](/docs/v3/4wings).

## Step 1: Retrieve Apparent Fishing Effort in Argentina's EEZ [#step-1-retrieve-apparent-fishing-effort-in-argentinas-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

<Tabs items="['cURL', 'Python', 'R', 'JavaScript']">
  <Tab value="cURL">
    ```shell
    # 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
        }
      }'
    ```
  </Tab>

  <Tab value="Python">
    ```python
    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},
    )
    ```
  </Tab>

  <Tab value="R">
    ```r
    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"
    )
    ```
  </Tab>

  <Tab value="JavaScript">
    ```js
    // 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()
    ```
  </Tab>
</Tabs>

> **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:**

```json
{
  "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 [#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

<Tabs items="['cURL', 'Python', 'R', 'JavaScript']">
  <Tab value="cURL">
    ```shell
    # 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
        }
      }'
    ```
  </Tab>

  <Tab value="Python">
    ```python
    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},
    )
    ```
  </Tab>

  <Tab value="R">
    ```r
    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')"
    )
    ```
  </Tab>

  <Tab value="JavaScript">
    ```js
    // 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()
    ```
  </Tab>
</Tabs>

**Example API Response:**

```json
{
  "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](/docs/v3/datasets).

**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 [#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

<Tabs items="['cURL', 'Python', 'R', 'JavaScript']">
  <Tab value="cURL">
    ```shell
    # 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]'
    ```
  </Tab>

  <Tab value="Python">
    ```python
    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"],
    )
    ```
  </Tab>

  <Tab value="R">
    ```r
    gfw_vessel_info(
      search_type = "id",
      ids = c("f38fb1980-0be3-d9d5-b166-877d9e9f3dc6"),
      includes = "POTENTIAL_RELATED_SELF_REPORTED_INFO"
    )
    ```
  </Tab>

  <Tab value="JavaScript">
    ```js
    // 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()
    ```
  </Tab>
</Tabs>

**Example API Response:**

```json
{
  "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 [#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 [#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](/docs/v3/events).
* **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

<Tabs items="['cURL', 'Python', 'R', 'JavaScript']">
  <Tab value="cURL">
    ```shell
    # 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]'
    ```
  </Tab>

  <Tab value="Python">
    ```python
    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,
    )
    ```
  </Tab>

  <Tab value="R">
    ```r
    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"
    )
    ```
  </Tab>

  <Tab value="JavaScript">
    ```js
    // 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()
    ```
  </Tab>
</Tabs>

**Example API Response:**

```json
{
  "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 [#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**
>
> * ✅ &#x2A;*Apparent Fishing Events:** The vessel "MEVIMAR" has been detected in multiple apparent fishing events during the analyzed timeframe (August 2024 – January 2025).
> * ✅ &#x2A;*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 [#summary-of-the-api-flow]

1. **4Wings API** → Retrieve apparent fishing effort for trawlers within Argentina's EEZ.
2. **Vessels API** → Fetch vessel identity, ownership history, and public authorizations.
3. **Events API** → Detect potential port visits, encounters, and apparent fishing events to analyze operational patterns.
4. **Assess potential risks** → Compare registry records, AIS data, and inferred vessel activity for enforcement follow-ups.
5. **Generate a report** → Provide a structured analysis for relevant authorities.
