Skip to content

API Reference

Complete reference for every method in the Meow client. Methods are grouped by feature.


Client

from meow_sdk import Meow

api = Meow(
    base_url="https://meowmeowscratch.com",  # optional
    username="jake",                           # for public reads
    api_key="YOUR_PLATFORM_TOKEN",             # for writes + management
)
Parameter Type Default Description
base_url str "https://meowmeowscratch.com" API base URL
username str None Required for public endpoint reads
api_key str None Required for writes, management, and private reads

Records

api.send(app, endpoint, data)

Send a new record to a collection endpoint. This is the main thing.

Parameter Type Description
app str App slug
endpoint str Endpoint slug
data dict Record data

Returns the created record (including uuid).

result = api.send("weather-station", "readings", {
    "temperature": 22.5,
    "humidity": 65,
})
print(result["uuid"])

api.send_many(app, endpoint, records)

Atomically create one to 100 records. records is a list of bare data dictionaries. The complete batch is validated before any row is stored.

result = api.send_many("weather-station", "readings", [
    {"temperature": 22.5, "humidity": 65},
    {"temperature": 22.7, "humidity": 64},
])
print(result["created"])

api.records(app, endpoint, limit=25, offset=0)

List records for an endpoint (paginated). Requires API key.

Parameter Type Default Description
app str App slug
endpoint str Endpoint slug
limit int 25 Records per page
offset int 0 Skip this many records

Returns {"count": N, "next": url, "previous": url, "results": [...]}.

page = api.records("weather-station", "readings", limit=10)
print(page["count"])
print(page["results"])

api.all_records(app, endpoint)

Fetch every record from an endpoint (auto-paginates). Requires API key.

Returns a flat list of all records.

everything = api.all_records("weather-station", "readings")
print(len(everything))

Note

This makes multiple API calls under the hood. For large datasets, prefer records() with pagination.


api.update(app, endpoint, record_id, data)

Update an existing record.

api.update("weather-station", "readings", "abc-123", {
    "temperature": 23.0,
})

api.delete_record(app, endpoint, record_id)

Delete a record.

api.delete_record("weather-station", "readings", "abc-123")

Public reads

These methods read from public endpoints. They require username but not an API key.

api.get(app, endpoint, **filters)

Read data from a public endpoint. Supports keyword argument filters.

api = Meow(username="jake")

# All records
data = api.get("weather-station", "readings")

# With filters
data = api.get("weather-station", "readings", temperature__gte=20)

api.get_record(app, endpoint, record_id)

Read a single public record by UUID.

record = api.get_record("weather-station", "readings", "abc-123")

api.aggregate(app, endpoint, aggregates, field=None, **filters)

Run aggregations on a collection endpoint.

Parameter Type Description
aggregates list[str] Functions: "avg", "min", "max", "sum", "count"
field str Field to aggregate on (required for avg/min/max/sum)
**filters Optional filters applied before aggregating
result = api.aggregate("weather-station", "readings",
    ["avg", "max"], field="temperature")
print(result["aggregations"]["avg"])

# With filters
result = api.aggregate("weather-station", "readings",
    ["avg"], field="temperature", location="London")

api.export_csv(app, endpoint, **filters)

Download records as a CSV string.

csv_data = api.export_csv("weather-station", "readings")

# Save to file
with open("data.csv", "w") as f:
    f.write(csv_data)

# With filters
csv_data = api.export_csv("weather-station", "readings", temperature__gte=20)

Apps

All app methods require an API key.

api.apps()

List your apps.

my_apps = api.apps()
for app in my_apps:
    print(app["slug"], app["name"])

api.get_app(slug)

Get details for a single app.

app = api.get_app("weather-station")
print(app["endpoint_count"])

api.create_app(name, slug, description="", is_public=False)

Create a new app.

Parameter Type Default Description
name str Display name
slug str URL slug (letters, numbers, hyphens)
description str "" Optional description
is_public bool False Whether endpoints are publicly readable
api.create_app("Weather Station", "weather-station")
api.create_app("Public Demo", "public-demo", is_public=True)

api.update_app(slug, **kwargs)

Update an app. Pass only the fields you want to change.

api.update_app("weather-station", name="My Weather Station")
api.update_app("weather-station", is_public=False, description="Private")

api.delete_app(slug)

Delete an app and all its endpoints, records, and config.

api.delete_app("old-project")

Endpoints

All endpoint methods require an API key.

api.endpoints(app)

List endpoints in an app.

eps = api.endpoints("weather-station")
for ep in eps:
    print(ep["slug"], ep["endpoint_type"])

api.get_endpoint(app, endpoint)

Get details for a single endpoint.

ep = api.get_endpoint("weather-station", "readings")
print(ep["record_count"])

api.create_endpoint(app, name, slug, endpoint_type="collection", description="", is_public=False)

Create a new endpoint.

Parameter Type Default Description
endpoint_type str "collection" "collection", "static", or "proxy"
api.create_endpoint("weather-station", "Readings", "readings")
api.create_endpoint("weather-station", "Status", "status", "static")
api.create_endpoint("weather-station", "Forecast", "forecast", "proxy")

api.update_endpoint(app, endpoint, **kwargs)

Update an endpoint. Pass only the fields you want to change.

api.update_endpoint("weather-station", "readings", name="Sensor Readings")
api.update_endpoint("weather-station", "readings", is_public=False)

api.delete_endpoint(app, endpoint)

Delete an endpoint and all its data.

api.delete_endpoint("weather-station", "old-endpoint")

Fields

Define the schema for collection endpoints. All methods require an API key.

api.fields(app, endpoint)

List fields for a collection endpoint.

schema = api.fields("weather-station", "readings")
for field in schema:
    print(field["name"], field["field_type"])

api.create_field(app, endpoint, name, label, field_type, required=False, default_value=None, options=None, help_text="", sort_order=0)

Create a new field.

Parameter Type Description
name str Machine name (used in record data)
label str Display label
field_type str One of the 14 types below
required bool Whether the field is required
default_value any Default value
options dict Type-specific options
help_text str Help text shown in forms
sort_order int Display order

Field types: text, textarea, number, boolean, date, datetime, time, color, email, url, select, rating, image_url, json

api.create_field("weather-station", "readings",
    "temperature", "Temperature", "number")

api.create_field("weather-station", "readings",
    "location", "Location", "text",
    required=True, help_text="City name")

api.create_field("weather-station", "readings",
    "mood", "Mood", "select",
    options={"choices": [
        {"value": "sunny", "label": "Sunny"},
        {"value": "cloudy", "label": "Cloudy"},
        {"value": "rainy", "label": "Rainy"},
    ]})

api.update_field(app, endpoint, field_uuid, **kwargs)

Update a field.

Once an endpoint contains records, name and field_type are immutable. Labels, required state, defaults, options, help text, and ordering remain editable.

api.update_field("weather-station", "readings", "uuid-123", label="Temp (C)")

api.delete_field(app, endpoint, field_uuid)

Delete a field from the schema.

api.delete_field("weather-station", "readings", "uuid-123")

api.field_types()

List all available field types. No authentication required.

types = api.field_types()
for t in types:
    print(t["value"], t["label"])

Static payloads

For endpoints with type "static". Requires an API key.

api.get_payload(app, endpoint)

Get the current static payload.

payload = api.get_payload("weather-station", "status")
# Returns the bare document. A new endpoint returns {}.

api.get_payload_state(app, endpoint)

Get the HTTP envelope when the update timestamp matters.

state = api.get_payload_state("weather-station", "status")
print(state["data"], state["updated_at"])

api.set_payload(app, endpoint, data)

Set (replace) the static payload.

api.set_payload("weather-station", "status", {
    "online": True,
    "version": "1.2",
    "message": "All systems go",
})

Proxy config

For endpoints with type "proxy". Requires an API key.

api.get_proxy(app, endpoint)

Get the proxy configuration.

config = api.get_proxy("weather-station", "forecast")

api.set_proxy(app, endpoint, upstream_url, method="GET", headers=None, query_params=None, body_template=None, jmespath_transform=None)

Configure a proxy endpoint to wrap an external API.

Parameter Type Default Description
upstream_url str The external URL to proxy
method str "GET" HTTP method
headers dict None Custom headers to send upstream
query_params dict None Query parameters to add
body_template dict None Request body template
jmespath_transform str None JMESPath expression to transform the response
api.set_proxy("weather-station", "forecast",
    "https://api.weather.com/v1/forecast",
    method="GET",
    headers={"X-Api-Key": "weather-key"},
    jmespath_transform="data.forecast[0]",
)

Encryption

Per-endpoint Fernet encryption. Requires an API key.

api.get_encryption(app, endpoint)

Check encryption status.

info = api.get_encryption("weather-station", "readings")
print(info["encryption_enabled"])

api.enable_encryption(app, endpoint)

Generate an encryption key and enable encryption.

Warning

The key is only shown once. Save it immediately.

result = api.enable_encryption("weather-station", "readings")
print(result["key"])  # save this!

api.disable_encryption(app, endpoint)

Disable encryption and delete the key.

api.disable_encryption("weather-station", "readings")

Request logs

api.request_logs(app, endpoint)

Get the last 50 API requests to an endpoint. Requires an API key.

logs = api.request_logs("weather-station", "readings")
for log in logs:
    print(log["method"], log["status_code"], f"{log['response_time_ms']}ms")

Webhooks

Requires an API key.

api.webhooks(app, endpoint)

List webhooks for an endpoint.

hooks = api.webhooks("weather-station", "readings")

api.get_webhook(app, endpoint, webhook_uuid)

Get a single webhook.

hook = api.get_webhook("weather-station", "readings", "uuid-123")

api.create_webhook(app, endpoint, target_url, events, secret=None, is_active=True)

Create a webhook.

Parameter Type Default Description
target_url str URL to send webhook payloads to
events list[str] Events to subscribe to
secret str None Signing secret for payload verification
is_active bool True Whether the webhook is active

Events: record.created, record.updated, record.deleted, payload.updated

api.create_webhook("weather-station", "readings",
    "https://example.com/hook",
    ["record.created", "record.updated"],
    secret="my-signing-secret",
)

api.update_webhook(app, endpoint, webhook_uuid, **kwargs)

Update a webhook. Pass only the fields you want to change.

api.update_webhook("weather-station", "readings", "uuid-123",
    is_active=False)

api.update_webhook("weather-station", "readings", "uuid-123",
    events=["record.created", "record.deleted"],
    target_url="https://new-url.com/hook")

api.delete_webhook(app, endpoint, webhook_uuid)

Delete a webhook.

api.delete_webhook("weather-station", "readings", "uuid-123")

Dashboards

See the Dashboards guide for a full walkthrough.

CRUD

Method Description
api.dashboards() List dashboards
api.get_dashboard(slug) Get dashboard details
api.create_dashboard(name, slug, description="") Create a dashboard
api.update_dashboard(slug, **kwargs) Update a dashboard
api.delete_dashboard(slug) Delete a dashboard

Widgets

Method Description
api.dashboard_widgets(dashboard) List widgets
api.create_dashboard_widget(dashboard, app, endpoint, key_path, widget_type, label, config=None, sort_order=0) Add a slug-bound widget
api.update_dashboard_widget(dashboard, widget_uuid, **kwargs) Update a widget
api.delete_dashboard_widget(dashboard, widget_uuid) Remove a widget

Data

Method Description
api.dashboard_state(dashboard) Read configured widget values
api.set_dashboard_widget_value(dashboard, widget_uuid, value) Write through a widget binding
api.public_dashboard(share_token) Read a public dashboard (no API key)

API keys

App-scoped keys for sharing access to a single app. Requires an API key.

api.app_keys(app)

List active API keys for an app.

keys = api.app_keys("weather-station")

api.create_app_key(app, name="Device key", scopes=None)

Create a new app-scoped API key.

Warning

The key is only shown once.

result = api.create_app_key(
    "weather-station", name="garden-pi", scopes=["read", "write"]
)
print(result["key"])  # save this!

api.delete_app_key(app, key_uuid)

Revoke an app-scoped API key.

api.delete_app_key("weather-station", "key-uuid-123")

Platform tokens

Personal tokens for SDK, CLI, and MCP authentication. Requires an API key.

api.platform_tokens()

List your platform tokens.

tokens = api.platform_tokens()

api.create_platform_token(name)

Create a new platform token.

Warning

The key is only shown once.

result = api.create_platform_token("My Raspberry Pi")
print(result["key"])  # save this!

api.revoke_platform_token(uuid)

Revoke a platform token.

api.revoke_platform_token("token-uuid-123")

Limits and authentication context

api.limits()

Get the enforced plan limits and remaining global capacity. Use a platform token and call this before provisioning a large schema or dashboard.

capacity = api.limits()
print(capacity["plan"], capacity["limits"]["fields_per_endpoint"])

api.auth_context()

Inspect the configured credential type, scopes, and app boundary without returning the credential itself.

api.billing_status() is deprecated because subscription and Stripe data require a browser session. Manage billing in the web app.