Migration Guide: Observation API V4 to V5

Overview

This guide provides comprehensive information for migrating from the InfoFlora Observation API V4 to V5. The V5 release (January 27, 2025) introduces significant improvements including enhanced filtering capabilities, Darwin Core alignment, and streamlined request/response formats.

Change Log Summary

Added

  • Filter operations for query parameters (eq, neq, gt, gte, lt, lte, in, not_in, wildcards, null checks)
  • Optional with_total parameter for list endpoints
  • New required field basis_of_record for observations
  • Darwin Core term references in property descriptions
  • Read-only fields: geodetic_datum, decimal_longitude, decimal_latitude

Changed

  • All endpoint paths from /v4/ to /v5/
  • Removed success property from GET responses
  • Removed unnecessary wrapper objects from POST/PUT payloads
  • Renamed multiple properties to align with Darwin Core specifications
  • Date format now includes milliseconds
  • observers is now recorded_by_id and accepts array of IDs directly

Removed

  • success property from response objects
  • Deprecated fields: taxon_expert, introduced_expert, municipality_id, municipality_expert, srid
  • Unnecessary data wrapper in request payloads
  • Always-present total counts (now opt-in via with_total parameter)

Breaking Changes

1. Base URL Path Change

V4: /rest/v4/...
V5: /rest/v5/...

All endpoint paths have been updated to use the v5 version prefix.

2. Response Envelope Changes

V4 Response Structure:

{
  "success": true,
  "data": { ... }
}

V5 Response Structure:

{
  "data": { ... }
}

The success property has been removed from all GET responses. Success and failure are indicated by HTTP status code.

3. POST/PUT Request Body Format

V4: Some endpoints wrapped payload data in a “data” object or specific property wrappers.

V5: The unnecessary wrapper objects have been removed from all POST and PUT payloads. Request bodies now directly contain the resource properties.

Query Parameter Filter Operations

One of the major improvements in V5 is the introduction of comprehensive filter operations for query parameters. See Request and Response Format for more details.

Filter Usage Examples

Basic filter:

GET /v4/observations?taxa=11018
GET /v5/observations?taxon_id[eq]=11018

Multiple filters:

GET /v4/observations?taxa=11018,11019&after=2024-01-01
GET /v5/observations?taxon_id[in]=11018,11019&event_date[gte]=2024-01-01

Null check:

GET /v5/observations?verbatim_identification[is_not_null]
GET /v5/observations?verbatim_identification[is_not_null]=true

Wildcard search:

GET /v5/observations?occurrence_remarks[iw_eq]=*foo*

Important Notes

  • Not all operations are available for all fields
  • Check the parameter description in the API documentation for allowed operations
  • List separators: Default operation is eq. If your filter use separators , or ~ you must specify operation in or not_in

Total Values in List Responses

V4 Behavior

Total counts were always returned in the response headers X-Total and X-Filtered-Total.

V5 Behavior

By default, responses with lists of objects are returned WITHOUT totals.

To retrieve totals, you must explicitly request them using the with_total query parameter:

GET /v5/observations?with_total=true

When with_total=true:

  • X-Total header: Total number of items in the database
  • X-Filtered-Total header: Number of items matching the current filters

Default value: false

Migration Impact

If your application relies on total counts:

  • Action Required: Add with_total=true to all list endpoint requests
  • Performance Benefit: If you don’t need totals, omit this parameter to improve response times. If you only need totals, prefer a HEAD request with the with_total=true query parameter.

POST and PUT Payload Format Changes

V4 Format

Some endpoints required wrapping the payload in a data or specific property object:

POST /v4/observations
{
  "observation": {
    "project_id": 12345,
    "date": "2024-01-15T10:00:00+01:00",
    "taxon_id": 11018,
    ...
  }
}

V5 Format

All unnecessary wrapper objects have been removed:

POST /v5/observations
{
  "dataset_id": 12345,
  "event_date": "2024-01-15T10:00:00+01:00",
  "taxon_id": 11018,
  ...
}

Note: While the outer wrapper might still exist for certain endpoints (like observations), the structure is more consistent and property names have been updated (see next section).

Migration Steps

  1. Review all POST and PUT request payloads in your code
  2. Remove any data wrapper objects
  3. Update property names according to the mapping table below
  4. Test all create and update operations

Property and Parameter Renaming

A significant number of properties have been renamed to align with Darwin Core specifications.

Observation Schema Property Mapping

V4 Property V5 Property Darwin Core Term
project_id dataset_id dwc:datasetID
releve_type event_type dwc:eventType
date event_date dwc:eventDate
observers recorded_by_id dwc:recordedByID
taxon_orig verbatim_identification dwc:verbatimIdentification
determinavit_cf identification_qualifier dwc:identificationQualifier
determinavit identified_by dwc:identifiedBy
introduced degree_of_establishment dwc:degreeOfEstablishment
locality_descript verbatim_locality dwc:verbatimLocality
x decimal_longitude dwc:decimalLongitude
y decimal_latitude dwc:decimalLatitude
geometry footprint_wkt dwc:footprintWKT
xy_type georeference_protocol dwc:georeferenceProtocol
xy_precision coordinate_uncertainty_in_meters dwc:coordinateUncertaintyInMeters
presence occurrence_status dwc:occurrenceStatus
srid geodetic_datum dwc:geodeticDatum

New Required Fields

V5 introduces new required fields:

V5 Property Description Vocabulary Field Name
basis_of_record Specific nature of the record basis_of_record

Deprecated Fields

The following V4 fields are deprecated and removed in V5:

  • taxon_expert
  • introduced_expert
  • municipality_id
  • municipality_expert
  • srid (replaced by geodetic_datum, which is read-only)

Vocabulary Field Name Changes

When looking up vocabulary values, note that fieldname in V4 becomes field_name in V5.

Example:

  • V4: fieldname = 'releve_type'
  • V5: field_name = 'releve_type'

Query Parameter Mapping

Query parameters have also been renamed to match the new property names:

V4 Parameter V5 Parameter
project_id dataset_id
date event_date
taxon_orig verbatim_identification

Response Format Changes

See Request and Response Format for more details.

Single Resource Response

V4:

{
  "success": true,
  "data": {
    "id": 123,
    "project_id": 12345,
    "date": "2024-01-15T10:00:00+01:00",
    ...
  }
}

V5:

{
  "data": {
    "id": 123,
    "dataset_id": 12345,
    "event_date": "2024-01-15T10:00:00.000+01:00",
    ...
  }
}

List Response

V4:

{
  "success": true,
  "data": [
    { ... },
    { ... }
  ]
}

Headers:

  • X-Total: 1000
  • X-Filtered-Total: 50

V5 (without totals):

{
  "data": [
    { ... },
    { ... }
  ]
}

V5 (with totals - using with_total=true):

{
  "data": [
    { ... },
    { ... }
  ]
}

Headers:

  • X-Total: 1000
  • X-Filtered-Total: 50

Migration Checklist

1. Update Base URLs

  • Change all API endpoints from /v4/ to /v5/
  • Update any hardcoded base URL constants in your code

2. Update Request Handling

POST/PUT Requests

  • Remove unnecessary data wrapper objects from request payloads
  • Update all property names in request bodies using the mapping table
  • Add new required field basis_of_record to observation payloads
  • Remove deprecated fields from payloads

GET Requests

  • Add with_total=true parameter to list endpoints if you need totals
  • Update query parameter names (e.g., project_iddataset_id)
  • Implement new filter operations as needed for enhanced filtering
  • Update date format parsing to handle milliseconds

3. Update Response Handling

  • Remove checks for success property in response parsing
  • Continue accessing data through the data property
  • Update property name references in response objects
  • Handle read-only fields like geodetic_datum, decimal_longitude, decimal_latitude

4. Vocabulary Updates

  • Update vocabulary lookup queries to use field_name instead of fieldname
  • Add handling for new vocabulary types (e.g., basis_of_record)

5. Error Handling

  • Review error response structures (generally unchanged, but verify)
  • Update any error message parsing if referencing renamed fields

6. Testing

  • Test all CRUD operations (Create, Read, Update, Delete)
  • Verify filter operations work as expected
  • Test edge cases with nullable fields
  • Validate date format handling
  • Confirm total count retrieval when needed
  • Test with both valid and invalid data

Additional Resources