API Reference
Reference for the Magmaro Creator API. Covers authentication, release automation, chunked uploads, licenses, campaigns and public discovery endpoints.
What the API Is For
The Magmaro Creator API is designed for release automation, creator data integrations, campaign management and public discovery. It is not a full replacement for the marketplace UI — the strongest use cases are automating new version releases from CI/CD pipelines, reading commercial data programmatically and managing campaigns without opening the web interface.
The API has two distinct surfaces. The creator surface requires an API key and an active Magmaro+ subscription. It exposes write operations for publishing, and read operations for transactions, licenses and campaigns. The public surface is read-only, requires no authentication, and is intended for lightweight external integrations such as in-game update checkers or community tools.
Base URL and Format
All endpoints share the same versioned base URL:
https://magmaro.com/api/v1
All requests and responses use JSON. Set the Accept: application/json header on every request to ensure error responses are also returned as JSON rather than HTML redirects. Write endpoints that accept a request body expect Content-Type: application/json unless a multipart/form-data upload is explicitly specified.
List endpoints return a consistent data array and a meta object containing pagination details. Single-entity endpoints return a data object. Error responses return a JSON object with a top-level message field and, for validation errors, an errors map of field names to error arrays.
Authentication
API keys are generated from My Account → Settings → Magmaro+ Settings → API Access. Magmaro shows the full plaintext key only once at creation time — copy it immediately and store it securely in a secrets manager, CI environment variable or deployment vault. It cannot be retrieved again after the initial display.
Pass your key in one of these two request headers — both are accepted:
Authorization: Bearer YOUR_API_KEY
X-API-Key: YOUR_API_KEY
To verify connectivity and key validity, call the /me endpoint:
curl https://magmaro.com/api/v1/me \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
{
"data": {
"id": 2,
"public_id": "xY1Djci26aAe",
"name": "Whiron",
"username": "whiron",
"email": "[email protected]",
"country": null,
"preferred_currency": "EUR",
"has_magmaro_plus": true,
"stripe_ready": true,
"api_key": {
"name": "Primary API Key",
"prefix": "mgmr_31YTwctUAQv",
"last_used_at": "2026-04-03T19:08:19+00:00",
"created_at": "2026-04-03T19:07:32+00:00"
}
}
}
If the key is valid but your Magmaro+ subscription has lapsed, creator endpoints will return 402. If the key itself is invalid or missing, you will receive 401.
Access Requirements
- API accessActive Magmaro+ subscription required
- Write endpointsStripe Connect onboarding must be complete
- Package uploadsChunked upload flow only — no single-request file upload
- Package size limitStandard accounts 100 MB / Magmaro+ 500 MB per version
- Temporal tokensOnly injected into JARs when creator has active Magmaro+
- Public endpointsNo API key or subscription required
Full Endpoint Surface
Creator API (API key + Magmaro+ required):
GET /api/v1/me
GET /api/v1/resources
GET /api/v1/resources/{resource}
GET /api/v1/resources/{resource}/download
GET /api/v1/resources/{resource}/versions/{resourceVersion}/download
POST /api/v1/resources/package-upload/chunk
POST /api/v1/resources/{resource}/versions
POST /api/v1/resources/{resource}/release
GET /api/v1/jobs
GET /api/v1/jobs/{job}
GET /api/v1/transactions
GET /api/v1/licenses
POST /api/v1/licenses/grant
GET /api/v1/offers
POST /api/v1/offers
DELETE /api/v1/offers/{offer}
GET /api/v1/coupons
POST /api/v1/coupons
DELETE /api/v1/coupons/{coupon}
GET /api/v1/ads
POST /api/v1/ads
DELETE /api/v1/ads/{booking}
Public API (no key required):
GET /api/v1/public/resources/search
GET /api/v1/public/resources/{resource}/latest-release
Route Keys
Magmaro uses opaque route keys rather than sequential integer IDs for most resources. A route key looks like a short alphanumeric string and is stable for the lifetime of the entity. Use GET /api/v1/resources to resolve the route key for a resource before targeting it with version or download endpoints. The route key is the value you pass as the {resource} path parameter in all resource-scoped endpoints.
Do not construct route keys from other data. They are assigned by the platform and cannot be predicted. Always resolve them from the list endpoint or from the platform UI before use.
Versioning and Stability
The current API version is v1, embedded in all endpoint paths. Magmaro will introduce a new version prefix if breaking changes are made to the API contract. Additive changes — new optional response fields, new optional request parameters — may be made within the current version without a version bump. Build your integrations to tolerate unknown JSON fields in responses.
List Creator Resources
GET /api/v1/resources returns a paginated list of your own resources. This is the primary way to resolve route keys before targeting a specific resource with version or download endpoints. Resources are returned with title, route key, status, category and basic metadata.
curl https://magmaro.com/api/v1/resources \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Supported query parameters:
per_page— results per page (default: 20, max: 100)page— page number (default: 1)
Get a Single Resource
GET /api/v1/resources/{resource} returns a single owned resource in full detail, including its current live version, pending version state, pricing, tags and metadata fields.
curl https://magmaro.com/api/v1/resources/RESOURCE_ROUTE_KEY \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Returns 403 if the resource belongs to a different creator. Returns 404 if the route key does not match any resource.
Download the Current Package
GET /api/v1/resources/{resource}/download downloads the current live package for the resource. The authenticated user must have access — either as the resource owner or as a buyer with the resource in their library. This endpoint also accepts a valid Magmaro temporal token for the same resource in place of a full API key.
curl -L https://magmaro.com/api/v1/resources/RESOURCE_ROUTE_KEY/download \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/octet-stream" \
-o resource-package.zip
The response is the raw file binary. Use -L in curl to follow the redirect if Magmaro issues one to a storage-layer URL. The file will be watermarked for the authenticated user at delivery time.
Download a Specific Version (Owner Only)
GET /api/v1/resources/{resource}/versions/{resourceVersion}/download targets a specific version package directly by its route key. This endpoint is only accessible by the resource owner — buyers are limited to the current live version via the standard download endpoint.
curl -L https://magmaro.com/api/v1/resources/RESOURCE_ROUTE_KEY/versions/VERSION_ROUTE_KEY/download \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/octet-stream" \
-o resource-version.zip
Useful for verifying a specific historical package or for internal testing of an older release. Returns 403 for non-owners regardless of library status.
Chunked Package Uploads
All resource package files must be uploaded using the chunked upload endpoint. This is the only supported upload path — single-request file uploads are not available. The chunked system handles large files reliably across slow or interrupted connections, and its idempotent design makes it safe to retry individual chunks without corrupting the upload.
Generate a stable upload_id for each build artifact. A good strategy is to derive it from your commit SHA, build number or release tag — for example my-plugin-v1.2.0-abc1234. Using a stable, unique ID means retrying the upload from any point is safe. Using a different ID for the same file would start a new independent upload.
Required multipart fields for each chunk request:
upload_id— your caller-controlled upload identifierfile_name— the original filename, including extension (e.g.myplugin.jar)chunk_index— zero-based index of this chunk (first chunk is0)total_chunks— total number of chunks in this uploadfile_size— the total file size in bytes across all chunkschunk— the binary content of this chunk as a multipart file field
Example — single chunk upload (file small enough to send as one chunk):
curl -X POST https://magmaro.com/api/v1/resources/package-upload/chunk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-F "upload_id=myplugin-v1.2.0-abc1234" \
-F "file_name=myplugin.jar" \
-F "chunk_index=0" \
-F "total_chunks=1" \
-F "file_size=204800" \
-F "[email protected]"
Example — multi-chunk upload (split into three parts using split):
split -b 5M myplugin.jar chunk_
CHUNKS=(chunk_aa chunk_ab chunk_ac)
TOTAL=${#CHUNKS[@]}
for i in "${!CHUNKS[@]}"; do
curl -X POST https://magmaro.com/api/v1/resources/package-upload/chunk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-F "upload_id=myplugin-v1.2.0-abc1234" \
-F "file_name=myplugin.jar" \
-F "chunk_index=$i" \
-F "total_chunks=$TOTAL" \
-F "file_size=$(wc -c < myplugin.jar)" \
-F "chunk=@${CHUNKS[$i]}"
done
After all chunks are received, the upload is finalised server-side and ready to be referenced when creating a version.
Create a Version
POST /api/v1/resources/{resource}/versions creates a new version record tied to a previously uploaded package. Pass the same upload_id you used during the chunk upload step. The version is submitted for moderation review and does not go live immediately.
curl -X POST https://magmaro.com/api/v1/resources/RESOURCE_ROUTE_KEY/versions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"version": "1.2.0",
"changelog": "Fixed reload command behavior. Improved compatibility with Paper 1.21.",
"package_upload_id": "myplugin-v1.2.0-abc1234"
}'
Required fields:
version— version string in any format, e.g.1.2.0,2024-04-07,beta-3changelog— description of changes in this version, supports plain textpackage_upload_id— theupload_idused in the chunk upload
Publish a Release (CI/CD Alias)
POST /api/v1/resources/{resource}/release is a semantic alias for creating a new version. It accepts the same fields and produces the same outcome — it exists so that CI/CD pipeline steps and deployment scripts read naturally when publishing to Magmaro.
curl -X POST https://magmaro.com/api/v1/resources/RESOURCE_ROUTE_KEY/release \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"version": "1.2.1",
"changelog": "Automated release from CI pipeline.",
"package_upload_id": "myplugin-v1.2.1-def5678"
}'
Typical CI/CD Flow
- Build your artifact (e.g.
mvn package,gradle shadowJar). - Derive an
upload_idfrom the commit SHA or build number. - Split and upload the artifact in chunks to
POST /api/v1/resources/package-upload/chunk. - Resolve the resource route key from
GET /api/v1/resourcesif not already cached. - Submit the release with the version string, changelog and
package_upload_id. - Magmaro receives the version and enters it into the moderation review queue.
- On approval, the new version becomes the live version for all buyers.
Java Example: Placeholders in a Plugin
For JAR files, Magmaro replaces placeholder strings in compiled Java class constant pools and embedded text files at delivery time. Declare placeholders as private static final string constants — the Java compiler will embed the string values in the class constant pool where Magmaro's delivery system can replace them. Do not expose them in config files or user-visible output unless that is specifically your intent.
package com.example.myplugin;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.bukkit.plugin.java.JavaPlugin;
public final class MyPlugin extends JavaPlugin {
private static final String MAGMARO_USERNAME = "%%__USERNAME__%%";
private static final String MAGMARO_RESOURCE = "%%__RESOURCE_TITLE__%%";
private static final String MAGMARO_VERSION = "%%__VERSION_NUMBER__%%";
private static final String TEMPORAL_TOKEN = "%%__MAGMARO_TEMPORAL_TOKEN__%%";
private static final long TOKEN_EXPIRES = %%__MAGMARO_TEMPORAL_TOKEN_EXPIRES__%%L;
private static final String RESOURCE_KEY = "your-resource-route-key";
@Override
public void onEnable() {
getLogger().info("Downloaded by: " + MAGMARO_USERNAME);
getLogger().info(MAGMARO_RESOURCE + " v" + MAGMARO_VERSION);
if (!TEMPORAL_TOKEN.isEmpty() && System.currentTimeMillis() / 1000L <= TOKEN_EXPIRES) {
checkForLatestPackage();
}
}
private void checkForLatestPackage() {
try {
URL url = new URL("https://magmaro.com/api/v1/resources/" + RESOURCE_KEY + "/download");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Authorization", "Bearer " + TEMPORAL_TOKEN);
conn.setRequestProperty("Accept", "application/octet-stream");
if (conn.getResponseCode() == 200) {
try (InputStream stream = conn.getInputStream()) {
getLogger().info("Magmaro package download accepted.");
}
}
} catch (Exception e) {
getLogger().warning("Failed to contact Magmaro: " + e.getMessage());
}
}
}
Important constraints on temporal tokens:
- Read-only — temporal tokens cannot perform any creator write operations
- Resource-scoped — a token for resource A cannot access resource B
- Maximum 60-day lifetime — always check
TOKEN_EXPIRESbefore use - Injected only when creator has active Magmaro+ — the placeholder will remain unreplaced if the subscription has lapsed
- Do not log, expose or transmit temporal tokens outside the plugin context
Jobs
GET /api/v1/jobs returns the creator's job listings with pagination. GET /api/v1/jobs/{job} returns a single job listing in full detail. Job endpoints are read-only through the API — creating or editing job listings requires the web interface.
curl https://magmaro.com/api/v1/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
curl https://magmaro.com/api/v1/jobs/JOB_ROUTE_KEY \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Transactions
GET /api/v1/transactions returns the creator's full transaction history with pagination. Useful for building revenue reporting scripts, internal dashboards, accounting exports or audit logs without manual downloads from the web interface.
curl "https://magmaro.com/api/v1/transactions?provider=stripe&range=30d&per_page=50" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Supported query parameters:
q— search by buyer username, resource title or transaction referenceprovider— filter by payment provider, e.g.stripecurrency— filter by transaction currency code, e.g.EUR,USDrange— date range shorthand:7d,30d,90d,1yper_page— results per page (default: 20, max: 100)page— page number
Each transaction record includes the resource identifier, buyer reference, gross amount, currency, provider, coupon used (if any) and timestamp. Revenue net of platform fees is computed separately based on applicable commission rates.
Licenses
GET /api/v1/licenses returns the full list of users currently holding a license for any of your resources. A license represents active access — either from a purchase or from a manual grant. This list is the API equivalent of the license table in your creator dashboard.
curl https://magmaro.com/api/v1/licenses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Supported query parameters:
resource_id— filter licenses to a specific resourceper_page— results per page (default: 20, max: 100)page— page number
The license list is useful for building server-side license validation logic — for example, a plugin that calls your own backend, which in turn queries this endpoint to verify that a server's owner holds a valid license before activating a feature.
Grant a License
POST /api/v1/licenses/grant manually grants a license for one of your resources to a specific Magmaro user. This is useful for migrations from other platforms, community giveaways, support resolutions where a refund was issued but access should be maintained, or beta access grants before a resource goes on sale.
curl -X POST https://magmaro.com/api/v1/licenses/grant \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"resource_id": 123,
"target_user": "buyer_username"
}'
The target_user field accepts either a Magmaro username or a registered email address. If the target user already holds a license for the specified resource, the endpoint returns a success response without creating a duplicate. Returns 404 if the target user does not exist. Returns 403 if the resource does not belong to the authenticated creator.
Offers
Offers apply a temporary percentage discount to a specific resource. When an offer is active, the discounted price is shown on all surfaces where the resource appears — catalog cards, search results, trending sections and the product page itself. The discount is applied automatically at checkout without any action required from the buyer.
GET /api/v1/offers returns your active and upcoming offers. POST /api/v1/offers creates a new offer. DELETE /api/v1/offers/{offer} cancels an offer before it ends.
curl https://magmaro.com/api/v1/offers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
curl -X POST https://magmaro.com/api/v1/offers \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"resource_id": 123,
"offer_percentage": 25,
"starts_at": "2026-04-10",
"ends_at": "2026-04-14"
}'
curl -X DELETE https://magmaro.com/api/v1/offers/OFFER_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Required fields: resource_id, offer_percentage (integer 1–99), starts_at and ends_at (ISO date strings). Offers are subject to platform cooldown rules — you cannot create a new offer immediately after one has ended on the same resource. The platform enforces maximum duration limits as well. Both are validated at creation time and return 422 with detail if violated.
Coupons
Coupons are code-based discounts that buyers apply manually at checkout. They are distinct from offers — a coupon requires the buyer to know and enter the code, while an offer is applied automatically. Use coupons for targeted promotions, newsletter campaigns, community events or partner referrals where you want to control who receives the discount.
GET /api/v1/coupons lists your coupons. POST /api/v1/coupons creates one. DELETE /api/v1/coupons/{coupon} removes it.
curl "https://magmaro.com/api/v1/coupons?is_active=true&per_page=50" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
curl -X POST https://magmaro.com/api/v1/coupons \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"resource_id": 123,
"code": "SPRINGDROP25",
"discount_percentage": 25,
"is_active": true
}'
curl -X DELETE https://magmaro.com/api/v1/coupons/COUPON_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Required fields: resource_id, code (unique per creator, case-insensitive), discount_percentage (integer 1–99), is_active (boolean). Coupon codes must be unique within your creator account. Attempting to create a duplicate code returns 422.
Supported query parameters for listing: is_active (boolean filter), per_page, page.
Ad Bookings
Ad bookings reserve specific calendar dates for promotional placement slots on the platform. You select a slot type and the dates you want your resource featured. Slots are first-come, first-served per date — once a date is booked for a given slot it is no longer available to other creators. Ad placements are independent of organic ranking and clearly commercial in nature.
GET /api/v1/ads returns your bookings. POST /api/v1/ads creates a booking. DELETE /api/v1/ads/{booking} cancels a future booking.
curl "https://magmaro.com/api/v1/ads?slot=featured&per_page=20" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
curl -X POST https://magmaro.com/api/v1/ads \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"resource_id": 123,
"slot": "featured",
"selected_dates": ["2026-04-20", "2026-04-21", "2026-04-22"]
}'
curl -X DELETE https://magmaro.com/api/v1/ads/BOOKING_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
Required fields: resource_id, slot (slot identifier string), selected_dates (array of ISO date strings). Dates that have already passed cannot be booked or cancelled. Attempting to cancel a past booking returns 422. If any date in selected_dates is already taken for the given slot, the entire request is rejected with 422 and the conflicting dates are listed in the error response.
Supported query parameters for listing: slot (filter by slot type), per_page, page.
Overview
The public API surface is open and requires no API key or authentication of any kind. It is designed for lightweight read-only integrations — community tools, bot lookups, in-game update checkers, external listing embeds and similar use cases where you need to query Magmaro data without managing credentials.
Because no authentication is required, the public surface is rate-limited more conservatively than the creator surface. It is not suitable for high-frequency polling or bulk catalog mirroring. For plugin update checks, use a reasonable polling interval — once per server startup or once per hour at most is appropriate. Excessive request rates may result in temporary IP-level throttling.
Public Resource Search
GET /api/v1/public/resources/search searches the public Magmaro catalog and returns matching resources. No API key required.
curl "https://magmaro.com/api/v1/public/resources/search?query=economy&game=Minecraft&limit=10" \
-H "Accept: application/json"
Supported query parameters:
query— keyword search against title and description contentgame— filter by game, e.g.Minecraft,Hytalecategory— filter by resource category slugauthor— filter by creator usernametype— filter by resource typesoftware— filter by software compatibility, e.g.Paper,Spigotlimit— maximum results to return (default: 20, max: 50)
Results include the resource title, route key, creator username, category, price, rating and cover image URL. Results are returned in relevance order for keyword queries, or by platform popularity when no keyword is specified.
Latest Release Metadata
GET /api/v1/public/resources/{resource}/latest-release returns metadata for the most recent approved release of a specific resource. No API key required. This endpoint is specifically designed for in-game version checkers, Discord bots and other tools that need to know the current version string or changelog without accessing the full product page.
curl https://magmaro.com/api/v1/public/resources/RESOURCE_ROUTE_KEY/latest-release \
-H "Accept: application/json"
The response includes the version string, changelog, release timestamp and any compatibility metadata attached to that version. It does not include download links — downloads require authentication and library access. Returns 404 if the resource does not exist or has no approved releases.
Example plugin-side usage: on server startup, fetch this endpoint with the resource route key hardcoded, compare the returned version string against the running version, and log a notice if a newer version is available. This approach works without Magmaro+ and without a temporal token.
Response Envelope
All list endpoints return a consistent response envelope. Empty collections return 200 OK with an empty data array — they do not return 404. Never treat an empty list as an error condition.
{
"data": [],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 20,
"total": 0,
"from": null,
"to": null
}
}
Single-entity endpoints return a top-level data object rather than an array:
{
"data": {
"id": "abc123",
"title": "My Resource",
...
}
}
Error Responses
Authentication failures and validation errors always return JSON — they never redirect to a login page or HTML error page. This makes the API safe to consume from scripts, CI environments and automated tools without HTML parsing or redirect handling.
400Malformed request — check request format and headers401Missing or invalid API key402Active Magmaro+ subscription required403Ownership check failed — resource belongs to a different creator404Resource, version or entity not found409Conflict — e.g. duplicate coupon code or already-licensed user422Validation error or business rule violation — seeerrorsmap in response429Rate limit exceeded — back off and retry after the indicated delay500Internal server error — retry with exponential backoff; if persistent, contact support
Validation error responses include a field-level breakdown:
{
"message": "The given data was invalid.",
"errors": {
"version": ["The version field is required."],
"package_upload_id": ["No completed upload found for this upload ID."]
}
}
Pagination
All list endpoints support cursor-free numeric pagination through page and per_page query parameters. The meta block in every list response contains current_page, last_page, per_page, total, from and to. Use last_page to determine whether additional pages exist before making a subsequent request.
curl "https://magmaro.com/api/v1/transactions?page=2&per_page=50" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
The default per_page value is 20 for most endpoints. The maximum is 100. Requesting more than 100 results per page will return a validation error.
Best Practices
- Store your API key in a secrets manager, CI environment variable or deployment vault. Never commit it to source control or embed it in client-side code.
- Rotate your key immediately if you suspect exposure. Old keys can be revoked from account settings and a new one generated without disrupting your account.
- Always send
Accept: application/jsonon every request to ensure error responses are machine-parseable JSON rather than HTML. - For release automation, use a deterministic
upload_idderived from your commit SHA or build number to make uploads idempotent and retry-safe. - Use temporal tokens for read-only plugin-side access. Do not use full API keys in distributed plugin code — temporal tokens are scoped, expiring and read-only by design.
- For version update checks in plugins, prefer the public
/latest-releaseendpoint over the authenticated download endpoint — it requires no credentials and has a much smaller response payload. - Implement exponential backoff when retrying on
5xxerrors. A transient infrastructure issue should not result in a broken CI pipeline — retry up to three times before failing the build. - Cache the
/api/v1/resourceslisting response in your CI pipeline to avoid resolving route keys on every build. Route keys are stable and do not change for the lifetime of a resource. - Build your integrations to tolerate unknown JSON fields in API responses. New fields may be added to existing response shapes as the API evolves within the current version.