SDK
The Cecil SDK is an open source Python library that allows you to use the Cecil platform. The SDK integrates with Cecil's internal API using standard HTTP methods, authentication, and response codes. Data resources use RFC 3339 timestamps and universally unique identifiers (UUID v4).
Source code: https://github.com/cecilearth/sdk
Release notes: https://github.com/cecilearth/sdk/blob/main/CHANGELOG.md
Installation
Install the SDK in your project virtual environment. Python ≥ 3.10 is required.
pip install cecilAuthentication
Configure the SDK by setting the CECIL_API_KEY environment variable. Only store your API key in an encrypted vault or secrets manager, never in code or plain/text files. Don't have an account? Sign up.
# Linux and macOS
export CECIL_API_KEY="my-api-key"
# Windows PowerShell
$env:CECIL_API_KEY = "my-api-key"Usage
All SDK functions require authentication unless otherwise specified.
import cecil
client = cecil.Client()
client.function_name()AOI
The area of interest (AOI) represents a geographic area.
Property | Type | Description |
|---|---|---|
| uuid | Unique identifier. |
| object | GeoJSON geometry object in |
| string | External reference in your system, e.g. AOI ID or name. |
| float | Total size derived from the geometry. This is useful for cost tracking. |
| datetime | Current system time in UTC when the AOI was created. |
| uuid | Authenticated user who created the AOI. |
The AOI geometry is a GeoJSON geometry object in EPSG:4326 delimiting the AOI boundaries.
Property | Type | Description |
|---|---|---|
| string | Polygon or MultiPolygon. |
| array | Nested array of coordinates according to the geometry |
Create AOI
This function allows you to create an AOI.
Input
client.create_aoi(
external_ref="123",
geometry={
"type": "Polygon",
"coordinates": [[
[132.52934211276073, -12.721072673008706],
[132.52934211276073, -12.730063400794094],
[132.54027735328083, -12.730063400794094],
[132.54027735328083, -12.721072673008706],
[132.52934211276073, -12.721072673008706],
]],
},
)Output
AOI(
id="fa200894-4e13-456c-872a-ba8efcda0812",
external_ref="123",
geometry={
"type": "Polygon",
"coordinates": [[
[132.52934211276073, -12.721072673008706],
[132.52934211276073, -12.730063400794094],
[132.54027735328083, -12.730063400794094],
[132.54027735328083, -12.721072673008706],
[132.52934211276073, -12.721072673008706],
]],
},
hectares=118.12168458669186,
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)List AOIs
This function allows you to list all AOIs in your organisation.
Input
client.list_aois()Output
[
AOI(
id="fa200894-4e13-456c-872a-ba8efcda0812",
external_ref="123",
hectares=118.12168458669186,
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
),
]Get AOI
This function allows you to get an AOI by ID.
Input
client.get_aoi("fa200894-4e13-456c-872a-ba8efcda0812")Output
AOI(
id="fa200894-4e13-456c-872a-ba8efcda0812",
external_ref="123",
geometry={
"type": "Polygon",
"coordinates": [[
[132.52934211276073, -12.721072673008706],
[132.52934211276073, -12.730063400794094],
[132.54027735328083, -12.730063400794094],
[132.54027735328083, -12.721072673008706],
[132.52934211276073, -12.721072673008706],
]],
},
hectares=118.12168458669186,
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)Dataset
The dataset represents a product offering by a data provider. All dataset information available in the SDK uses the same source of truth as the list of datasets in the documentation.
Property | Type | Description |
|---|---|---|
| uuid | Unique identifier. |
| string | Dataset name. |
| string | Data provider name. |
| string | Category as specified in the Cecil dataset documentation. |
| string | Data type: |
| string | CRS as specified in the Cecil dataset documentation. |
| string | Version number as published by the data provider. |
| string | Release date for the corresponding version number. |
List datasets
This function allows you to list all datasets available in the Cecil platform.
Input
client.list_datasets()Output
[
Dataset(
id="f42f8f48-6cf9-48af-8453-be6cca46acb8",
name="Protected Species",
provider_name="Acme Earth",
category="Biodiversity integrity",
type="Raster",
crs="EPSG:4326",
version_number="1.0",
version_date="2025",
),
]Subscription
The subscription represents a dataset acquisition for your AOI.
Property | Type | Description |
|---|---|---|
| uuid | Unique identifier. |
| string | Unique identifier of the AOI associated with this subscription. |
| string | Unique identifier of the dataset associated with this subscription. You can find this information on the details page of available datasets. |
| string | External reference in your system, e.g. data subscription ID, use case ID, or description of the use case. |
| datetime | Current system time in UTC when the subscription was created. |
| uuid | Authenticated user who created the subscription. |
Create subscription
This function allows you to acquire datasets for your AOI. This process runs in the background and may take from a few minutes to a few business days depending on the data provider.
Input
client.create_subscription(
aoi_id="fa200894-4e13-456c-872a-ba8efcda0812",
dataset_id="f42f8f48-6cf9-48af-8453-be6cca46acb8",
external_ref="123",
)Output
Subscription(
id="f644efb3-8ba4-4bc4-8333-1ace54a3f111",
aoi_id="fa200894-4e13-456c-872a-ba8efcda0812",
dataset_id="f42f8f48-6cf9-48af-8453-be6cca46acb8",
external_ref="123",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)List subscriptions
This function allows you to list all subscriptions in your organisation.
Input
client.list_subscriptions()Output
[
Subscription(
id="f644efb3-8ba4-4bc4-8333-1ace54a3f111",
aoi_id="fa200894-4e13-456c-872a-ba8efcda0812",
dataset_id="f42f8f48-6cf9-48af-8453-be6cca46acb8",
external_ref="123",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
),
]Get subscription
This function allows you to get a subscription by ID.
Input
client.get_subscription("f644efb3-8ba4-4bc4-8333-1ace54a3f111")Output
Subscription(
id="f644efb3-8ba4-4bc4-8333-1ace54a3f111",
aoi_id="fa200894-4e13-456c-872a-ba8efcda0812",
dataset_id="f42f8f48-6cf9-48af-8453-be6cca46acb8",
external_ref="123",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)Data access
You can access Cecil datasets with the following functions.
Function | Dataset type |
|---|---|
Load xarray |
|
Load dataframe |
|
Load xarray
This function allows you to load a raster dataset into an xarray.Dataset. Raster datasets always have x, y dimensions and most times a time dimension. The following metadata is available in dataset-level attributes. See datasets for usage notes.
Dimension | Type | Units |
|---|---|---|
| Per dataset variable | Per CRS. |
| Per dataset variable | Per CRS. |
| datetime | Per dataset, when a time dimension is available. |
Metadata |
|---|
|
|
|
|
|
Input
client.load_xarray(
subscription_id="f644efb3-8ba4-4bc4-8333-1ace54a3f111",
)Output
<xarray.Dataset> Size: 3MB
Dimensions: (x: 50, y: 50, time: 20)
Coordinates:
* x (x) float64 512B 68.57 68.57 68.57 ... 68.56 68.56
* y (y) float64 512B 45.78 45.78 45.78 ... 45.76 45.76 45.76
* time (time) datetime64[ns] 2kB 2021-03-21 ... 2025-12-21
Data variables:
canopy_cover (x, y, time) float64 3MB dask.array<chunksize=(50, 50, 1), meta=np.ndarray>
canopy_height (x, y, time) float64 3MB dask.array<chunksize=(50, 50, 1), meta=np.ndarray>
Attributes:
provider_name: Planet
dataset_name: Forest Carbon Monitoring
dataset_id: f42f8f48-6cf9-48af-8453-be6cca46acb8
aoi_id: fa200894-4e13-456c-872a-ba8efcda0812
subscription_id: f644efb3-8ba4-4bc4-8333-1ace54a3f111Load dataframe
This function allows you to load a vector dataset into a pandas.DataFrame. Vector datasets have the following metadata in dataframe columns. See datasets for usage notes.
Metadata |
|---|
|
|
Input
client.load_dataframe(
subscription_id="f644efb3-8ba4-4bc4-8333-1ace54a3f111",
)Output
canopy_cover timestamp
0 0.73 datetime.datetime(2021, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC))
1 0.79 datetime.datetime(2022, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC))
2 0.87 datetime.datetime(2023, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC))
[3 rows x 2 columns]Webhooks
Webhooks allow you to receive real-time event notifications from the Cecil platform. The webhook url must use HTTPS, handle POST requests, and return a 200 status within 10 seconds. Failed requests will be retried 5 times every 60 seconds, and then again 30 times every 12 hours.
Property | Type | Description |
|---|---|---|
| string | Your application URL to receive webhook events. |
| string | Optional secret for signature validation. |
Configure webhook
This function allows you to configure your organisation webhook.
Input
client.configure_webhook(
url="https://api.example.com/cecil-webhook",
secret="YT5MzU9xk3dhMDjZ",
)Output
Webhook(
url="https://api.example.com/cecil-webhook",
)Delete webhook
This function allows you to delete the webhook configuration, stopping notifications immediately.
Input
client.delete_webhook()Output
No contentSignature validation
We recommend you to use the Cecil-Signature header to validate the authenticity and integrity of webhook events. Below is a code example in Python.
import hashlib
import hmac
body = "raw body received in the http request"
signature = "Cecil-Signature http header"
secret = "webhook-secret"
digest = hmac.new(
digestmod=hashlib.sha256
key=secret.encode("utf-8"),
msg=body.encode("utf-8"),
).hexdigest()
if hmac.compare_digest(digest, signature):
print("valid")Events
Webhook notifications include the following events.
Event name | Event type |
|---|---|
Subscription delivered |
|
Subscription failed |
|
Subscription delivered
This event notifies that a data chunk has been delivered for a Subscription.
For datasets with a time dimension, this includes all pixels for a specific variable and time step.
For datasets without a time dimension, this includes all pixels for a specific variable and an explicit
nullvalue for thepayload.timeproperty.
Example
{
"event_id": "f309e366-13dc-5f6c-8cad-c0c3c34bb548",
"event_type": "subscription.delivered",
"payload": {
"aoi_id": "fa200894-4e13-456c-872a-ba8efcda0812",
"subscription_id": "f644efb3-8ba4-4bc4-8333-1ace54a3f111",
"dataset_id": "f42f8f48-6cf9-48af-8453-be6cca46acb8",
"dataset_type": "raster",
"time": "2026-01-09T00:00:00Z",
"variable": "x_value"
},
"recorded_at": "2026-01-01T15:30:09.033Z"
}Subscription failed
This event notifies that a Subscription has failed to process. Possible failures are due to data not being found for the specified AOI, or due to technical constraints from data providers, in which case, the payload.error_message contains the original error message from the data provider.
Example
{
"event_id": "f309e366-13dc-5f6c-8cad-c0c3c34bb548",
"event_type": "subscription.failed",
"payload": {
"aoi_id": "fa200894-4e13-456c-872a-ba8efcda0812",
"subscription_id": "f644efb3-8ba4-4bc4-8333-1ace54a3f111",
"dataset_id": "f42f8f48-6cf9-48af-8453-be6cca46acb8",
"dataset_type": "vector",
"error_message": "Data not found."
},
"recorded_at": "2026-01-01T15:30:09.033Z"
}Organisation settings
Organisation settings allow you to configure the following organisation-wide settings.
Property | Type | Description |
|---|---|---|
| integer | Number of hectares across subscriptions that can be created per month. This value can only be configured for verified organisations. Please contact us to verify your organisation. Default: 50,000. |
Get organisation settings
This function allows you to view your organisation settings.
Input
client.get_organisation_settings()Output
OrganisationSettings(
monthly_subscription_limit=50_000,
)Update organisation settings
This function allows you to update your organisation settings.
Input
client.update_organisation_settings(
monthly_subscription_limit=50_000,
)Output
OrganisationSettings(
monthly_subscription_limit=50_000,
)User management
User management allows creating and viewing users in your organisation.
Property | Type | Description |
|---|---|---|
| uuid | Unique identifier. |
| string | First name. |
| string | Last name. |
| string | Email address. |
| datetime | Current system time in UTC when the user was created. |
| uuid | Authenticated user who created the user. |
Create user
This function allows you to create an organisation user. The new user will receive an email with instructions to generate their API key. The link sent via email expires in 7 days. If the link expires, the recover function can be used to generate their API key.
Input
client.create_user(
first_name="John",
last_name="Smith",
email="john.smith@greenfield.com",
)Output
User(
id="624e5cc3-aaf3-4b35-a92b-352f0d102daf",
first_name="John",
last_name="Smith",
email="john.smith@greenfield.com",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)List users
This function allows you to list all users in your organisation.
Input
client.list_users()Output
[
User(
id="624e5cc3-aaf3-4b35-a92b-352f0d102daf",
first_name="John",
last_name="Smith",
email="john.smith@greenfield.com",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
),
]Get user
This function allows you to get a user by ID.
Input
client.get_user("624e5cc3-aaf3-4b35-a92b-352f0d102daf")Output
User(
id="624e5cc3-aaf3-4b35-a92b-352f0d102daf",
first_name="John",
last_name="Smith",
email="john.smith@greenfield.com",
created_at=datetime.datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=TzInfo(UTC)),
created_by="51f9cf7c-78f5-49e0-b6fd-ba281346ae3f",
)API key management
We recommend all users to automatically rotate their API keys on a regular basis. Users can also recover their API key via email.
Rotate API key
This function allows users to rotate their API key. This is useful to improve your organisation security by implementing an automated process that rotates API keys on a regular basis.
Input
client.rotate_api_key()Output
RotateAPIKey(
new_api_key="NzhjMWQwNjE1OGRhZDYxZDkxMWZlZjU1MWI1OTVlMmIK",
)Recover API key
This function allows users to recover their API key via email. If we find a user with the email address provided, the user will receive an email with instructions to recover their API key. The link sent via email expires in 7 days. This function doesn’t require authentication.
Input
client.recover_api_key("jane.doe@foo.com")Output
RecoverAPIKey(
message="Please follow the instructions sent via email.",
)