Documentation

Everything you need to integrate SOAPless into your application.

On This Page

Jump to setup, method policies, testing, API keys, and troubleshooting.

API Reference →

Start in 3 steps

Register a WSDL, issue an API key, and make the first JSON request.

Choose GET vs POST

Understand service defaults, per-operation overrides, and when GET is exposed.

Use exact endpoint shapes

Jump straight to path format, headers, status codes, and OpenAPI-related behavior.

Quick Start

Get up and running with SOAPless in three steps.

What you get after setup

A stable account-scoped endpoint, JSON request and response handling, API key auth, and optional GET support for read-style operations.

Step 1: Register Your WSDL Service

Add your SOAP service in the dashboard. Provide the WSDL URL and optional SOAP credentials. SOAPless will parse the WSDL and generate REST endpoints automatically.

Step 2: Create an API Key

Generate an API key from the API Keys page. Copy it immediately — the full key is shown only once.

Step 3: Make Your First Request

Call your new REST endpoint. In the default configuration, POST with JSON works:

First requestbash
curl -X POST https://soapless.miravy.com/api/v1/ab12cd34ef/my-service/GetUser \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sl_live_your_api_key_here" \
  -d '{"userId": 42}'

GET can also be enabled automatically for read-style operations, or enabled manually per operation on paid plans:

GET examplebash
curl "https://soapless.miravy.com/api/v1/ab12cd34ef/my-service/GetSum?a=2&b=3" \
  -H "X-API-Key: sl_live_your_api_key_here"

Authentication

All API requests must include your API key in the X-API-Key header.

Authentication headerhttp
POST /api/v1/{accountId}/{serviceSlug}/{operationName} HTTP/1.1
Host: soapless.miravy.com
Content-Type: application/json
X-API-Key: sl_live_your_api_key_here

GET requests use the same X-API-Key header and omit the JSON body.

API keys are scoped to your account and can be created, rotated, or revoked at any time from the dashboard. We recommend using separate keys for each environment (development, staging, production).

Upstream SOAP authentication

If the SOAP service itself requires authentication, you can configure it per service in the dashboard. HTTP Basic Auth is available on all plans, WS-Security on Starter and above, and custom outbound headers on Pro.

  • HTTP Basic Auth: for upstream services that expect a standard username and password over HTTP.
  • WS-Security: for SOAP services that expect a UsernameToken in the SOAP header.
  • Custom header: for proprietary tokens or gateway headers that must be sent with each outbound request.

Stored SOAP credentials are encrypted at rest. In the edit screen, leaving credential fields blank keeps the current stored value.

Making Requests

SOAPless exposes each SOAP operation as a REST endpoint:

POST /api/v1/{accountId}/{serviceSlug}/{operationName}
GET /api/v1/{accountId}/{serviceSlug}/{operationName}

GET is available for read-style operations with simple query-safe inputs, or when you explicitly enable GET for that operation in the dashboard on a paid plan.

  • accountId: Your stable public Account ID from Settings (e.g., ab12cd34ef).
  • serviceSlug: The slug you assigned when registering your WSDL service (e.g., my-erp).
  • operationName: The SOAP operation name from the WSDL (e.g., GetUser).

Send JSON in the request body. SOAPless converts it to the appropriate SOAP XML envelope, calls the upstream service, and returns the response as JSON.

  • POST is supported by default. It can be disabled per operation with a manual GET-only policy.
  • GET can be added automatically for read-style operations or manually per operation on Starter and Pro.
  • GET additionally requires a read-like operation name such as GetUser, ListOrders, or GetSum.
  • GET additionally requires every input field to be a top-level primitive: string, number, integer, or boolean.
  • Manual per-operation method policies are preserved across WSDL refresh for matching operation names.
  • If an operation has nested objects or arrays, use POST.

Method Policies In The Dashboard

Each service has a default method strategy, and each operation can optionally override it.

  • Inherit: Use the service default.
  • POST: Force POST only for that operation.
  • GET: Force GET only when the input schema is query-safe.
  • GET + POST: Expose both methods when the input schema is query-safe.
  • When both methods are available, dashboard examples prefer GET for read-like operations and POST otherwise.
  • Operation-level policies are available on Starter and Pro plans.
  • Changing a policy refreshes the API Explorer and OpenAPI output immediately.

Testing Operations

The service detail page includes a session-authenticated test panel for trying operations without creating an API key first.

  • Example JSON is generated from the operation schema to help you start with a valid request.
  • When an operation supports both GET and POST, the test panel lets you switch between them before executing.
  • SOAP faults are normalized into readable messages instead of raw object dumps.
  • The test panel is for manual verification. Production clients should use the generated REST endpoints with API keys.

Response Format

Successful responses return a JSON object with result and meta fields:

Success responsejson
{
  "result": {
    "id": 42,
    "name": "Alice Johnson",
    "email": "alice@acme.com",
    "department": "Engineering"
  },
  "meta": {
    "service": "my-erp",
    "operation": "GetUser",
    "latencyMs": 245
  }
}

Error Format

Error responses return a consistent JSON structure:

Error responsejson
{
  "error": {
    "type": "VALIDATION_ERROR",
    "code": 400,
    "message": "Missing required field: userId"
  }
}

The type field is a machine-readable error category. The message field provides a human-readable description. See the API Reference for a full list of error types.

Rate Limits

Usage limits are tracked at the account level, not per API key. Free accounts receive HTTP 429 after reaching the monthly cap, while paid plans can continue and incur overage billing.

PlanMonthly LimitRate LimitOverage
Free100 calls10 req/minBlocked
Starter ($29/mo)10,000 callsNo limit$0.01/call
Pro ($99/mo)100,000 callsNo limit$0.01/call

Rate limit headers are included in every response:

Rate limit headershttp
X-RateLimit-Limit: 10000
X-RateLimit-Remaining: 9542
X-RateLimit-Reset: 2026-04-01T00:00:00Z

Authentication Details

SOAPless uses API keys for authentication. Here is everything you need to know about creating and using them.

Getting Your API Key

  1. Sign in to the dashboard.
  2. Navigate to API Keys.
  3. Click "Create API Key" and give it a descriptive name.
  4. Copy the key immediately. The full key (sl_live_...) is shown only once.

Including the API Key

Pass your key in the X-API-Key header on every request. Both proxy calls and the OpenAPI spec endpoint accept this header.

Header formathttp
GET /api/services/{id}/openapi HTTP/1.1
Host: soapless.miravy.com
X-API-Key: sl_live_your_api_key_here

Key Security Best Practices

  • Store keys in environment variables, never in source code.
  • Use separate keys per environment (dev, staging, prod).
  • Rotate keys periodically from the dashboard.
  • Revoke compromised keys immediately.

curl Examples

Common operations you can perform from the command line or CI pipelines.

Proxy Call

Proxy a SOAP operationbash
curl -X POST https://soapless.miravy.com/api/v1/ab12cd34ef/my-erp/GetUser \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sl_live_abc123" \
  -d '{"userId": 42}'

Fetch OpenAPI Spec

Download the auto-generated OpenAPI 3.0 spec for a service (requires a paid plan).

Download OpenAPI specbash
curl -H "X-API-Key: sl_live_abc123" \
  https://soapless.miravy.com/api/services/{service-id}/openapi \
  -o my-service-openapi.json

Inspect Rate Limit Headers

View response headersbash
curl -v -X POST https://soapless.miravy.com/api/v1/ab12cd34ef/my-erp/GetUser \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sl_live_abc123" \
  -d '{"userId": 42}' 2>&1 | grep -i x-ratelimit

Error Handling

SOAPless returns consistent error JSON. Here is how to handle the most common errors in your code.

401 Unauthorized

Your API key is missing, invalid, or revoked. Double-check the X-API-Key header and ensure the key has not been revoked in the dashboard.

401 responsejson
{
  "error": {
    "type": "auth",
    "code": "INVALID_API_KEY",
    "message": "Invalid API key"
  }
}

429 Too Many Requests

You have exceeded your monthly quota (Free plan) or per-minute rate limit. Check the X-RateLimit-Reset header to know when the current period resets. Free accounts are blocked at the monthly cap, while paid plans continue with overage billing.

429 responsejson
{
  "error": {
    "type": "rate_limit",
    "code": "MONTHLY_LIMIT_EXCEEDED",
    "message": "Monthly API call limit exceeded (100 calls for free plan)."
  }
}

502 Bad Gateway

The upstream SOAP service is unreachable or returned a SOAP Fault. This is not a SOAPless issue. Verify the SOAP service is up and check the error.detail field for the original fault message.

502 responsejson
{
  "error": {
    "type": "upstream",
    "code": "SOAP_FAULT",
    "message": "Upstream SOAP service returned a fault",
    "detail": "Server was unable to process request: timeout"
  }
}

Retry Strategy

JavaScript retry examplejavascript
async function callWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fetch(url, options);

    if (res.status === 429) {
      const resetAt = res.headers.get("X-RateLimit-Reset");
      const waitMs = resetAt
        ? new Date(resetAt).getTime() - Date.now()
        : 1000 * Math.pow(2, attempt);
      await new Promise((r) => setTimeout(r, waitMs));
      continue;
    }

    if (res.status === 502 && attempt < maxRetries - 1) {
      await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, attempt)));
      continue;
    }

    return res;
  }
  throw new Error("Max retries exceeded");
}

SDK Examples

Code snippets for calling the SOAPless proxy from popular languages.

JavaScript / TypeScript

JavaScript examplejavascript
const response = await fetch(
  "https://soapless.miravy.com/api/v1/ab12cd34ef/my-erp/GetUser",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key": process.env.SOAPLESS_API_KEY,
    },
    body: JSON.stringify({ userId: 42 }),
  }
);

if (!response.ok) {
  const err = await response.json();
  throw new Error(err.error.message);
}

const { result, meta } = await response.json();
console.log(result);  // { id: 42, name: "Alice Johnson", ... }
console.log(meta);    // { latencyMs: 245, ... }

Python

Python examplepython
import os
import requests

response = requests.post(
    "https://soapless.miravy.com/api/v1/ab12cd34ef/my-erp/GetUser",
    headers={
        "Content-Type": "application/json",
        "X-API-Key": os.environ["SOAPLESS_API_KEY"],
    },
    json={"userId": 42},
    timeout=30,
)
response.raise_for_status()

data = response.json()
print(data["result"])   # {'id': 42, 'name': 'Alice Johnson', ...}
print(data["meta"])     # {'latencyMs': 245, ...}

Go

Go examplego
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	body, _ := json.Marshal(map[string]int{"userId": 42})
	req, _ := http.NewRequest(
		"POST",
		"https://soapless.miravy.com/api/v1/ab12cd34ef/my-erp/GetUser",
		bytes.NewReader(body),
	)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-API-Key", os.Getenv("SOAPLESS_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	fmt.Println(result["result"])
}

Monitoring & Usage

SOAPless provides built-in tools to monitor your API usage.

Usage Dashboard

Track your monthly API calls, latency trends, and error rates in real time from the dashboard. Reset timing depends on the active plan and billing period, so it is not always the first day of the month.

Rate Limit Headers

Every response includes rate limit headers so you can proactively manage your usage:

  • X-RateLimit-Limit — Your call limit for the current plan.
  • X-RateLimit-Remaining — Calls remaining in the current period.
  • X-RateLimit-Reset — ISO 8601 timestamp when the current limit window resets.

Account operations

Billing changes, invoices, card updates, and cancellations are handled from the dashboard billing page and Stripe Customer Portal. Permanent account deletion stays available in dashboard settings.

Email is reserved for security reports, privacy requests, legal matters, enterprise inquiries, or account access issues that cannot be resolved from the dashboard.

Next Steps