API v2.4 documentation for CoastSnap

API Overview

Endpoint Description
oauth2/access_token Get an access token for authenticating api calls.
Includes documentation on how to make an authenticated api call.
api/v2.4/activities/import Import an activity.
api/v2.4/comments List comments.
api/v2.4/spots List spots.
api/v2.4/spots/{id} Get spot details.

Get access token

Endpoint: https://www.spotteron.com/oauth2/access_token
Method: POST
Content-type: application/x-www-form-urlencoded
Request body:
Name Required Type Info
grant_type true TEXT client_credentials (see below in appendix)
client_id true TEXT topic_37_api for CoastSnap
client_secret true TEXT Your secret

Appendix

Using the SPOTTERON API with Client Credentials Flow

Overview

OAuth 2.0 is an authorization framework that allows applications to obtain limited access to a user’s resources without exposing their credentials. The Client Credentials flow is a specific OAuth 2.0 flow designed for machine-to-machine (M2M) authentication, where the client (app) can access resources on its own behalf rather than on behalf of a user.

Client Credentials are bound to a user account. Currently, clients have all permissions as the user it is bound to. This might be restricted in the future, so a client could have only a subset of the permission given to a user.

Prerequisites

Understanding the Client Credentials Flow

In this flow:

  1. Your client (application) authenticates itself with the authorization server by providing the client ID and client secret.
  2. The authorization server verifies the credentials and returns an access token.
  3. Your client uses this access token to access protected resources on behalf of itself.

Getting Started with the Client Credentials Flow

Step 1: Register Your Application

Contact Spotteron to get a Client ID and Client Secret.

Step 2: Define the Required Parameters

When requesting an access token, you’ll need the following parameters:

Requesting an Access Token

The access token request is typically made to the Token URL via a POST request. Example Request:

Use a POST request to obtain an access token. Here’s an example using curl:

curl -X POST \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  https://www.spotteron.com/api/v2/access_token

Replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with the appropriate values. Note: Always use HTTPS to protect credentials.

Sample Response:

If successful, the authorization server responds with a JSON object containing an access_token, token_type, and sometimes expires_in.

{
  "access_token": "your_access_token_here",
  "token_type": "Bearer",
  "expires_in": 3600
}

Using the Access Token

Once you have the access token, you can make requests to the API on behalf of your application. Include the access token in the Authorization header of your API requests. Example Request with Access Token:

Use curl to make a request to the API endpoint with the access token:

curl -X GET \
  -H "Authorization: Bearer your_access_token_here" \
  https://www.spotteron.com/resource

Explanation:

Handling Expired Tokens

Access tokens have a limited lifetime (defined by expires_in in the token response). Once the token expires, you’ll need to request a new one using the same client_credentials request flow.

To manage expired tokens:

Track the token's expiry time based on the expires_in value. Re-authenticate (repeat the token request) when the token expires.

Error Handling

The authorization server may return errors if something goes wrong. Common errors include:

Example Error Response:

Invalid client:

{
  "error":"invalid_client",
  "error_description":"Client authentication failed",
  "message":"Client authentication failed"
}

Tips for Error Handling:

Sample Implementation

Here’s a quick implementation in Python using the requests library to automate the process. Python Example:

import requests

# OAuth2 details
token_url = "https://www.spotteron.com/oauth2/access_token"
client_id = "YOUR_CLIENT_ID"
client_secret = "YOUR_CLIENT_SECRET"

# Request an access token
response = requests.post(
    token_url,
    data={
        "grant_type": "client_credentials",
        "client_id": client_id,
        "client_secret": client_secret
    }
)

# Parse the token response
if response.status_code == 200:
    access_token = response.json().get("access_token")
    print("Access Token:", access_token)

    # Use the access token to access a protected resource
    api_url = "https://www.spotteron.com/resource"
    api_response = requests.get(
        api_url,
        headers={"Authorization": f"Bearer {access_token}"}
    )

    # Print the response from the API
    print("API Response:", api_response.json())
else:
    print("Failed to obtain access token:", response.json())

Security Considerations

Summary

This manual covers all the steps to authenticate using OAuth 2.0 Client Credentials flow and access protected resources.

Import activity

Endpoint: https://www.spotteron.com/api/v2.4/activities/import
Authentication: Bearer token
Method: POST
Content-Type: multipart/form-data
Request body:
Name Required Type Info
data[attributes][type_id] true TEXT The activity type id:
1 for event
data[attributes][topic_id] true TEXT The topic id:
37 for CoastSnap
data[attributes][category] true TEXT Categories for event activities:
  • general
  • event
  • workshop
  • field_trip
  • area_of_interest
data[attributes][title][ca-ES]
data[attributes][title][es-ES]
data[attributes][title][fr-FR]
data[attributes][title][gl-ES]
data[attributes][title][nl-NL]
data[attributes][title][pt-PT]
data[attributes][title][en-AU]
true TEXT The title of the activity.
en-AU is required
data[attributes][description][ca-ES]
data[attributes][description][es-ES]
data[attributes][description][fr-FR]
data[attributes][description][gl-ES]
data[attributes][description][nl-NL]
data[attributes][description][pt-PT]
data[attributes][description][en-AU]
TEXT The description of the activity.
data[attributes][image] FILE Activity image. Content-Type: image/jpeg
data[attributes][location][ca-ES]
data[attributes][location][es-ES]
data[attributes][location][fr-FR]
data[attributes][location][gl-ES]
data[attributes][location][nl-NL]
data[attributes][location][pt-PT]
data[attributes][location][en-AU]
TEXT The location name of the activity
data[attributes][geometry_type] TEXT None, Point, Circle or GeoJSON
data[attributes][geometry] TEXT The GeoJSON if geometry type is GeoJSON
data[attributes][latitude] TEXT The latitude if geometry type is Point or Circle
data[attributes][longitude] TEXT The longitude if geometry type is Point or Circle
data[attributes][radius] TEXT The radius if geometry type is Circle
data[attributes][start] TEXT Start date/time of the activity.
Format "YYYY-MM-DD hh:mm"
data[attributes][end] TEXT End date/time of the activity.
Format "YYYY-MM-DD hh:mm"
data[attributes][timezone] TEXT The timezone identifier, e.g. Europe/Vienna
data[attributes][source_id] TEXT An external unique identifier.
If endpoint is called with the same source id twice, the existing dataset with the same source id will be overwritten.

List comments

Endpoint: https://www.spotteron.com/api/v2.4/comments
Authentication: Bearer token
Method: GET
Return format: JSON
Parameter:
Name Required Type Info
filter[id__gt] INT Get comments with id greater than given value
filter[id__lt] INT Get comments with id lower than given value
filter[topic_id] true INT Filter by topic id, 37 for CoastSnap
filter[target_type] INT Get comments for a specific content type:
  • 1 for User
  • 3 for Spot
filter[target_id] INT Get comments for a specific content id. Use in conjunction with target_type.
filter[root_id] INT Filter by root comment id. (Get replies to a comment)
filter[created_at__gt] STRING Get comments created after a given date, Format: "YYYY-MM-DD hh:mm"
filter[created_at__lt] STRING Get comments created before a given date, Format: "YYYY-MM-DD hh:mm"
filter[created_by] INT Get comments created by given user id
filter[is_root] INT Get only root comments
filter[is_reply] INT Get only replies to root comments
order[] STRING e.g. “id DESC”
limit INT API is limited to max. 100 comments per request/page
page INT
Example:
Get the latest 10 comments
https://www.spotteron.com/api/v2.4/comments?filter[topic_id]=37&limit=10&page=1&order[]=id+desc

List spots

Endpoint: https://www.spotteron.com/api/v2.4/spots
Authentication: Bearer token
Method: GET
Return format: JSON
Parameter:
Name Required Type Info
filter[topic_id] true INT Filter by topic id, 37 for CoastSnap
filter[category] INT Filter by project category
filter[longitude__gt] FLOAT Get spots with longitude greater than given value
filter[longitude__lt] FLOAT Get spots with longitude lower than given value
filter[latitude__gt] FLOAT Get spots with latitude greater than given value
filter[latitude__lt] FLOAT Get spots with latitude lower than given value
filter[created_at__gt] STRING Get spots created after a given date, Format: "YYYY-MM-DD hh:mm"
filter[created_at__lt] STRING Get spots created before a given date, Format: "YYYY-MM-DD hh:mm"
filter[modified_at__gt] STRING Get spots modified after a given date, Format: "YYYY-MM-DD hh:mm"
filter[modified_at__lt] STRING Get spots modified before a given date, Format: "YYYY-MM-DD hh:mm"
filter[id__gt] INT Get spots with id greater than given value
filter[id__lt] INT Get spots with id lower than given value
filter[period] STRING Filter spots by period: "day", "week", "month" or "year"
filter[root_id] INT Get spots with given root id
filter[spotted_by] INT Get spots spotted by given user id
filter[is_featured] INT Get top spots only (1)
order[] STRING e.g. “id DESC”
limit INT API is limited to max. 100 spots per request/page
page INT
Example:
Get the latest 10 spots
https://www.spotteron.com/api/v2.4/spots?filter[topic_id]=37&limit=10&page=1&order[]=id+desc

Get spot details

Endpoint: https://www.spotteron.com/api/v2.4/spots/{id}
Authentication: Bearer token
Method: GET
Return format: JSON

Appendix

Project related attributes

Some attributes returned by the spot service are related to CoastSnap. They are encoded by field type and id. Here you can find the name for each attribute:

Attribute Name
fld_07_00000751 checkbox_location
fld_21_00002448 image_gallery
fld_01_00001214 name_of_location
fld_05_00000671 changes_last_update
fld_06_00000672 reason_for_change
fld_01_00000673 other_cause
fld_07_00000674 advanced_options
fld_05_00000675 image_capture_type
fld_05_00000676 tide_level
fld_05_00000677 diy_method
fld_11_00000679 photo_height
fld_01_00000678 spot_name

Attribute related values

Some attributes represent option fields. The options are encoded as follows:

category Id
Coastsnap Station 3442
Diy Station 3443
Free Roaming 3444
changes_last_update (fld_05_00000671) Id
Coast Has Grown (Accretion) 3445
Coast Has Narrowed (Erosion) 3446
No Obvious Change 3447
reason_for_change (fld_06_00000672) Id
Tide 3448
Waves 3449
Wind 3450
Storm 3451
Human Activity 3452
Climate Change 3454
Natural Trend 3455
Other 3456
image_capture_type (fld_05_00000675) Id
Snapshot (Standard) 3457
Time-averaged (Advanced) 3458
tide_level (fld_05_00000676) Id
Low Tide 3459
Rising Tide 3460
High Tide 3461
Falling Tide 3462
diy_method (fld_05_00000677) Id
Fixed Post,Handrail 3463
Tripod 3464
Coastsnap Starter Kit 3465
Other 3466