Common API automation recipes
Quick answer
Four patterns cover most day-to-day API automation: polling status on a schedule, rotating an API key before it expires, sending a Slack alert through a webhook, and forwarding webhook events into your own systems. All of them authenticate the same way, with an X-API-Key header, and all of them need to respect the API's rate limit of 200 requests per minute per IP address.
The API returns HTTP 429 with a
Retry-Afterheader once you go over 200 requests per minute per IP. Any script that polls on a schedule, like the one below, should check for a 429 and back off for the duration in that header rather than retrying immediately.
1. Check server status on a schedule
A cron job that polls an endpoint and reacts to the result is the simplest form of automation, and often the first thing teams set up. This example checks a server's status every five minutes and writes a line to a log file if it isn't running.
# crontab -e
*/5 * * * * /usr/local/bin/check-server-status.sh >> /var/log/server-status.log 2>&1#!/usr/bin/env bash
# check-server-status.sh
# Illustrative pattern only, take the exact endpoint path from Portal's API reference.
set -euo pipefail
API_KEY="<your-api-key>"
SERVER_ID="<server-id>"
STATUS_URL="https://api.worldstream.com/<family>/v1/<command>/$SERVER_ID"
status=$(curl -s -H "X-API-Key: $API_KEY" \
"$STATUS_URL" | jq -r '.status')
echo "$(date -u +%FT%TZ) server=$SERVER_ID status=$status"
if [ "$status" != "running" ]; then
echo "WARNING: $SERVER_ID is not running (status: $status)"
fiKeep the API key out of the script itself. Read it from an environment variable or a secrets manager, and give the key only the permissions it needs, read-only status access rather than a full-access key, if your key permissions support that level of granularity.
2. Rotate an API key before it expires
Keys are created under Developers → API → Keys in Portal with a Key Name, an Expires In value (30 days, 90 days, 180 days, or 1 year), and a Permissions level (Full access, Read only, or Custom). Once that expiry date passes, the key stops working. Rather than waiting for a script to fail in production, generate the replacement key ahead of time and swap it over in your secrets store.
If your account has the API IP allowlist set to Enforce, make sure the host creating the new key is on the allowlist first, otherwise the request that creates it will be denied. Check Recent API key denials on the Keys tab if a rotation script starts failing with a 403.
#!/usr/bin/env bash
# rotate-api-key.sh
# Illustrative pattern only, check the current endpoint in Portal's API reference.
set -euo pipefail
OLD_KEY="<current-api-key>"
new_key_response=$(curl -s -X POST \
-H "X-API-Key: $OLD_KEY" \
-H "Content-Type: application/json" \
-d '<request body, see the API reference in Portal>' \
"https://api.worldstream.com/<family>/v1/<command>")
new_key=$(echo "$new_key_response" | jq -r '.secret')
# Store the new key in your secrets manager here, then update
# whatever reads it (CI variables, a systemd EnvironmentFile, etc.)
echo "New key created, store it now: $new_key"
# Only revoke the old key once every consumer has been switched over.Treat key rotation as a two-step process: create and roll out the new key first, confirm everything that depends on it still works, then revoke the old one. Revoking the old key before the new one is in place everywhere will break anything still using it.
3. Send a Slack alert when an event fires
This one doesn't use the API directly, it uses Webhooks, a separate feature under Developers → Webhooks in Portal. Add a webhook there with a Slack-compatible destination URL and set its format to Slack, then narrow it down with the optional, comma-separated Topics field (leave it empty to receive every event type). Take the topic names from the Webhooks page in Portal. Worldstream posts to the URL when the event happens, you don't need to poll for it.
Create the webhook
In Portal, go to Developers → Webhooks and select Add webhook. Give it a name, paste in your Slack incoming webhook URL (it must be HTTPS), and set the format to Slack so the payload matches what Slack expects.
Send a test event
Use the Test action on the webhook's row to confirm it reaches Slack before relying on it.
Keep the signing secret
The signing secret is shown once when the webhook is created. Store it if your receiving side needs to verify that a payload genuinely came from Worldstream, rather than relying on the destination URL being HTTPS alone.
Only enable topics you actually want to act on. A webhook that fires on every event type tends to get muted or ignored, which defeats the point of using one.
4. Forward webhook events into your own monitoring or ticketing system
If Slack isn't where your team tracks things, set the webhook's format to Generic JSON instead and point it at an endpoint you control, such as a small receiver that forwards events into your monitoring stack, ticketing system, or internal chat tool.
# Illustrative receiver, adapt the framework and payload
# handling to whatever your monitoring/ticketing system expects.
# The event_type value below ("resource.event") is a placeholder.
# Use the real topic and event names shown on the Webhooks page in Portal.
from flask import Flask, request
app = Flask(__name__)
@app.route("/webhooks/worldstream", methods=["POST"])
def worldstream_webhook():
payload = request.get_json()
event_type = payload.get("event")
if event_type == "resource.event":
# forward into your own system here
pass
return "", 204Verify incoming requests against the signing secret before acting on them, so a request that merely knows your endpoint URL can't trigger anything on its own. Take the exact verification method (which header carries the signature, and how it is computed) from the Webhooks documentation in Portal.