Morphemeris DocsBeta

Batch Requests

How to compute positions across date ranges and mix endpoint types in a single API call.

Batch Requests

The batch endpoint lets you send up to 50 computation requests in a single HTTP call. This is ideal for computing positions across date ranges, comparing data at multiple moments, or combining different endpoint types.

Computing a Year of Daily Sun Positions

Instead of making 365 individual requests, send them all in one batch:

Bash
curl -X POST https://api.morphemeris.com/v1/batch \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [
      { "endpoint": "/v1/positions", "params": { "datetime": "2024-01-01T00:00:00Z", "bodies": "sun" } },
      { "endpoint": "/v1/positions", "params": { "datetime": "2024-01-02T00:00:00Z", "bodies": "sun" } },
      { "endpoint": "/v1/positions", "params": { "datetime": "2024-01-03T00:00:00Z", "bodies": "sun" } }
    ]
  }'

Each result includes the full position data at the corresponding index:

JSON
{
  "data": {
    "results": [
      { "index": 0, "status": 200, "data": [{ "body": "sun", "longitude": 280.35, "..." }] },
      { "index": 1, "status": 200, "data": [{ "body": "sun", "longitude": 281.37, "..." }] },
      { "index": 2, "status": 200, "data": [{ "body": "sun", "longitude": 282.39, "..." }] }
    ],
    "summary": { "total": 3, "succeeded": 3, "failed": 0 }
  },
  "meta": { "credits_used": 3, "..." }
}

Since the maximum batch size is 50, a full year requires 8 batches of 50 requests each (365 / 50). This uses 365 credits total, the same as individual requests, but with 8 HTTP round-trips instead of 365.

Mixing Endpoint Types

A batch can combine different endpoints. For example, compute a full chart (positions + houses) at one moment and also get the Delta T and sidereal time:

Bash
curl -X POST https://api.morphemeris.com/v1/batch \
  -H "Authorization: Bearer morphemeris_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "requests": [
      {
        "endpoint": "/v1/chart",
        "params": {
          "datetime": "1990-06-15T14:30:00Z",
          "lat": 40.7128,
          "lon": -74.006,
          "bodies": "planets"
        }
      },
      { "endpoint": "/v1/delta-t", "params": { "datetime": "1990-06-15T14:30:00Z" } },
      { "endpoint": "/v1/sidereal-time", "params": { "datetime": "1990-06-15T14:30:00Z", "lon": -74.006 } }
    ]
  }'

This costs 3 credits (1 + 1 + 1) and returns chart data, Delta T, and sidereal time in a single response.

Handling Partial Failures

If one sub-request has an error (e.g., missing a required parameter), the other sub-requests still succeed:

JSON
{
  "data": {
    "results": [
      { "index": 0, "status": 200, "data": [{ "body": "sun", "..." }] },
      {
        "index": 1,
        "status": 400,
        "error": {
          "code": "missing_parameter",
          "message": "Exactly one of 'datetime' or 'jd' must be provided.",
          "param": "datetime"
        }
      },
      { "index": 2, "status": 200, "data": { "delta_t_seconds": 56.17, "..." } }
    ],
    "summary": { "total": 3, "succeeded": 2, "failed": 1 }
  }
}

Check the summary.failed count and inspect individual result status codes to handle errors programmatically.

Building Batch Requests Programmatically

In Python:

Python
import requests
from datetime import datetime, timedelta

# Compute Sun/Moon positions for the first 50 days of 2024
base = datetime(2024, 1, 1)
sub_requests = [
    {
        "endpoint": "/v1/positions",
        "params": {
            "datetime": (base + timedelta(days=i)).strftime("%Y-%m-%dT00:00:00Z"),
            "bodies": "sun,moon"
        }
    }
    for i in range(50)
]

resp = requests.post(
    "https://api.morphemeris.com/v1/batch",
    headers={"Authorization": "Bearer morphemeris_live_YOUR_KEY"},
    json={"requests": sub_requests}
)

data = resp.json()
for result in data["data"]["results"]:
    if result["status"] == 200:
        positions = result["data"]
        # Process positions...

In JavaScript:

javascript
const dates = Array.from({ length: 50 }, (_, i) => {
  const d = new Date(2024, 0, 1 + i);
  return d.toISOString();
});

const response = await fetch("https://api.morphemeris.com/v1/batch", {
  method: "POST",
  headers: {
    Authorization: "Bearer morphemeris_live_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    requests: dates.map((dt) => ({
      endpoint: "/v1/positions",
      params: { datetime: dt, bodies: "sun,moon" },
    })),
  }),
});

const { data } = await response.json();
const succeeded = data.results.filter((r) => r.status === 200);

Tips

  • Credit cost is the same whether you batch or send individual requests. Batching saves HTTP overhead, not credits.
  • Rate limiting counts the batch as 1 request, so batching is more efficient than parallel individual requests.
  • Each sub-request is independent. There is no way to share common parameters across sub-requests. Build shared params into each sub-request client-side.
  • Maximum 50 sub-requests per batch. For larger workloads, split into multiple batch calls.