Documentation

From API key to first request in minutes.

AssetMeld uses an OpenAI-compatible interface, so most existing integrations only need three changes: your API key, the AssetMeld base URL and the model ID.

On this page Quickstart
QuickstartAuthenticationCompatibilityChat CompletionsResponses APIStreamingTool CallingVisionStructured OutputsModelsCompatibilityBillingRate LimitsTimeoutsErrorsModels EndpointRequest IDsMigrationReasoningHeadersModel IDsCostPrivacyDeprecationStatusTroubleshootingSecurityProductionSupport

Quickstart

Get your first response in three steps: create an API key, install the OpenAI SDK, and send a request.

1. Get your API key

Create an account, verify your email, and generate an API key from the dashboard. The full key is shown only once — copy it and store it securely.

2. Set your API key

export ASSETMELD_API_KEY="am_live_..."

Never hard-code API keys in source code. Use environment variables or a secrets manager.

3. Send your first request

Install the OpenAI Python SDK and send a chat completion:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ASSETMELD_API_KEY"],
    base_url="https://api.assetmeld.com/v1",
)

response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "Hello!"}],
)

print(response.choices[0].message.content)

Other languages

curl https://api.assetmeld.com/v1/chat/completions \
  -H "Authorization: Bearer $ASSETMELD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-sol",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ASSETMELD_API_KEY,
  baseURL: "https://api.assetmeld.com/v1",
});

const response = await client.chat.completions.create({
  model: "gpt-5.6-sol",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(response.choices[0].message.content);

Authentication

All requests require a valid API key passed in the Authorization header:

Authorization: Bearer am_live_...

API key lifecycle

  • Create: generate from the API keys dashboard. The key secret is shown only once.
  • Rotate: create a new key, update your application, then revoke the old key.
  • Revoke: revocation takes effect immediately. No requests will be accepted.

If your key is compromised: revoke it immediately, create a new one, and check your usage dashboard for unexpected activity.

OpenAI Compatibility

AssetMeld implements an OpenAI-compatible API surface for supported endpoints. Compatibility does not imply that every OpenAI parameter is supported by every model.

Most applications using the OpenAI SDK can migrate by changing three things:

  1. API key
  2. Base URL → https://api.assetmeld.com/v1
  3. Model ID

How parameters are handled

  • Direct: fields the model accepts as-is.
  • Unsupported: parameters not supported by the selected model return 400 with unsupported_parameter. They are not silently ignored.

Supported endpoints

  • POST /v1/chat/completions — Chat Completions
  • POST /v1/responses — Responses API
  • POST /v1/messages — Messages API (Anthropic SDK)

Chat Completions

POST /v1/chat/completions

Request parameters

FieldTypeRequiredDescription
modelstringYesModel ID from the catalog
messagesarrayYesConversation messages
temperaturenumberNoSampling temperature (0–2). Default varies by model.
top_pnumberNoNucleus sampling (0–1)
max_tokensintegerNoMaximum output tokens
streambooleanNoEnable Server-Sent Events streaming (default: false)
toolsarrayNoTool/function definitions
tool_choicestring/objectNoTool selection behavior (auto, none, or specific)
response_formatobjectNoStructured output (json_object or json_schema)
stopstring/arrayNoStop sequences

Message roles

RoleDescription
systemSystem instructions
userUser message
assistantModel response (include in multi-turn)
toolTool execution result

Response format

{
  "id": "chatcmpl_xxx",
  "object": "chat.completion",
  "created": 1787390000,
  "model": "gpt-5.6-sol",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Hello!"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 6,
    "total_tokens": 18
  }
}

finish_reason values

  • stop — model finished naturally
  • length — hit max_tokens limit
  • tool_calls — model wants to call a tool
  • content_filter — output was filtered

Responses API

POST /v1/responses

The Responses API is an OpenAI-compatible endpoint with a slightly different request shape. It supports the same models as Chat Completions.

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ASSETMELD_API_KEY"],
    base_url="https://api.assetmeld.com/v1",
)

response = client.responses.create(
    model="gpt-5.6-sol",
    input="Explain TCP congestion control simply.",
)

print(response.output_text)
curl https://api.assetmeld.com/v1/responses \
  -H "Authorization: Bearer $ASSETMELD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-sol",
    "input": "Explain TCP congestion control simply."
  }'

Messages API — Anthropic SDK

POST /v1/messages

/v1/messages is the native Anthropic Messages surface. Point the Anthropic (Qwen) SDK at AssetMeld and use any enabled model ID — including advanced controls such as adaptive thinking and effort levels.

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ASSETMELD_API_KEY"],
    base_url="https://api.assetmeld.com/v1",
)

response = client.chat.completions.create(
    model="claude-opus-5",
    messages=[{"role": "user", "content": "Explain TCP congestion control simply."}],
)

print(response.choices[0].message.content)

With adaptive thinking enabled, the response stream includes a dedicatedthinking block plus standard message_start,content_block_delta, and message_stop events — the same event signature as the native Messages API.

curl https://api.assetmeld.com/v1/messages \
  -H "Authorization: Bearer $ASSETMELD_API_KEY" \
  -H "Content-Type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5",
    "max_tokens": 1024,
    "thinking": {"type": "adaptive", "display": "omitted"},
    "messages": [{"role": "user", "content": [{"type": "text", "text": "Explain TCP congestion control simply."}]}]
  }'

Streaming

Enable streaming with stream=True to receive partial responses as they are generated. AssetMeld uses Server-Sent Events (SSE) compatible with the OpenAI streaming protocol.

stream = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "Explain DNS simply"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)

Streaming behavior

  • Each chunk contains a delta with partial content
  • The final chunk has finish_reason and empty delta
  • Usage is included in the final chunk when available
  • If the client disconnects mid-stream, usage already generated may still be charged

Tool Calling

Tool-capable models can request that your application execute functions. AssetMeld never executes tools automatically — your application must handle the full tool-use loop.

Flow

  • 1. Send request with tools definitions
  • 2. Model returns tool_calls in the response
  • 3. Your application validates and executes the tool
  • 4. Send tool result back as a tool message
  • 5. Model generates the final answer
import os, json
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ASSETMELD_API_KEY"],
    base_url="https://api.assetmeld.com/v1",
)

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name"}
                },
                "required": ["city"],
            },
        },
    }
]

# Step 1: Send request with tools
response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[{"role": "user", "content": "What is the weather in Hanoi?"}],
    tools=tools,
)

message = response.choices[0].message

# Step 2: Check for tool calls
if message.tool_calls:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)

    # Step 3: Execute the tool (your code)
    weather_result = {"temperature": 31, "condition": "Cloudy"}

    # Step 4: Send tool result back
    messages = [
        {"role": "user", "content": "What is the weather in Hanoi?"},
        message,
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(weather_result),
        },
    ]

    # Step 5: Get final answer
    final = client.chat.completions.create(
        model="gpt-5.6-sol",
        messages=messages,
        tools=tools,
    )
    print(final.choices[0].message.content)

Important notes

  • Treat tool arguments as untrusted input — validate before executing
  • Parallel tool calls: models may return multiple tool calls at once
  • Tool support varies by model — check the model catalog for badges

Vision

Models with the Vision badge accept image inputs. Send images as URLs or base64-encoded data within the messages array.

Image URL

response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Describe this image."},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://example.com/photo.jpg"
                    },
                },
            ],
        }
    ],
)

Base64

import base64

with open("photo.jpg", "rb") as f:
    image_data = base64.standard_b64encode(f.read()).decode()

response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is in this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{image_data}"
                    },
                },
            ],
        }
    ],
)

Vision notes

  • Supported formats: JPEG, PNG, WebP
  • Image tokens count toward input usage
  • Check the model catalog for vision support — text-only models reject images with 400 unsupported_model_feature

Structured Outputs

Request structured JSON output with response_format:

# JSON mode
response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[...],
    response_format={"type": "json_object"},
)

# JSON Schema mode
response = client.chat.completions.create(
    model="gpt-5.6-sol",
    messages=[...],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "person",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string"},
                    "age": {"type": "integer"},
                },
                "required": ["name", "age"],
            },
        },
    },
)

Switching Models

The same client can call any enabled model. Change the model parameter and keep the rest of your integration:

model="gpt-5.6-sol"
model="claude-opus-5"
model="kimi-k3"

Your application code, authentication and base URL stay the same. Browse the full catalog on the Models page.

SDK compatibility

Tested and compatible: OpenAI Python SDK, OpenAI JavaScript/TypeScript SDK, and raw HTTP (any language). Other frameworks (LangChain, LiteLLM, Vercel AI SDK) may work but are not officially tested.

Billing

AssetMeld uses prepaid billing. You are charged for tokens used on each request at the rates in effect when the request starts. Prices may change; the price active when your request begins is the price that applies.

Request lifecycle

  • 1. We estimate the maximum cost upfront and hold it from your balance
  • 2. Inference begins
  • 3. After completion, final cost is calculated
  • 4. You pay only for tokens used — the rest is returned to your balance immediately

What is charged

ScenarioCharged?
Successful responseYes — input + output tokens
Stream generates tokens, client disconnectsPartial — usage already generated
Invalid request (400)No
Invalid API key (401)No
Server error before inferenceNo
Rate limited (429)No

Adding balance

Top-ups are currently manual. Follow the PayPal or crypto instructions in your billing dashboard, keep your PayPal transaction ID, and contact AssetMeld on Telegram with your account email and transaction ID.

Balance updates are manual and are applied only after the payment is independently verified.

Rate Limits

Requests are subject to per-key and per-account rate limits. When a limit is exceeded, AssetMeld returns HTTP 429 with rate_limit_exceeded.

Retry strategy

HTTPRetry?Action
400NoFix the request
401NoCheck API key
402NoAdd balance
429YesRespect Retry-After, exponential backoff with jitter
500YesRetry with backoff
502YesRetry with backoff
503YesRetry with backoff
504YesRetry with backoff
import random, time

max_retries = 5

for attempt in range(max_retries):
    try:
        response = client.chat.completions.create(...)
        break
    except Exception:
        if attempt == max_retries - 1:
            raise
        delay = min(2 ** attempt + random.random(), 30)
        time.sleep(delay)

Error Handling

Every AssetMeld response includes an X-Request-ID header. Include it when contacting support.

Error response format

{
  "error": {
    "code": "rate_limit_exceeded",
    "type": "rate_limit_error",
    "message": "Rate limit exceeded. Please retry after backoff.",
    "param": null
  }
}

Stable error codes

Use error.code for programmatic handling. The human-readable message may change.

CodeHTTPMeaning
invalid_api_key401Missing, malformed, or revoked key
invalid_request400Malformed JSON or missing required fields
unsupported_parameter400Parameter not supported by this model
unsupported_model_feature400Feature not supported (e.g., vision on text-only model)
model_not_found400Model ID does not exist
model_disabled400Model exists but is disabled
insufficient_balance402Not enough prepaid balance
rate_limit_exceeded429Too many requests — back off
model_timeout504Model did not respond in time
model_unavailable502Model returned an error

Error examples

// 402 — Insufficient balance
{
  "error": {
    "code": "insufficient_balance",
    "type": "billing_error",
    "message": "Insufficient prepaid balance.",
    "param": null
  }
}
// 400 — Unsupported feature
{
  "error": {
    "code": "unsupported_model_feature",
    "type": "invalid_request_error",
    "message": "Model gpt-5.6-sol does not support image input.",
    "param": "messages"
  }
}

Models Endpoint

GET /v1/models

Returns the list of enabled models available to your API key.

curl https://api.assetmeld.com/v1/models \
  -H "Authorization: Bearer $ASSETMELD_API_KEY"
{
  "object": "list",
  "data": [
    {"id": "gpt-5.6-sol", "object": "model"},
    {"id": "claude-opus-5", "object": "model"},
    {"id": "kimi-k3", "object": "model"}
  ]
}

Request IDs

Every API response includes an X-Request-ID header. Log this value and include it in support requests for fast debugging.

response = client.chat.completions.create(...)
request_id = response._request_id  # or response.headers["x-request-id"]

Migrate from OpenAI

What usually works unchanged

  • Chat completions
  • Streaming
  • Tool calling
  • Message format
  • Python and JavaScript SDKs

What may differ

  • Supported parameters (model-dependent)
  • Model IDs (use AssetMeld catalog IDs)
  • Rate limits
  • Reasoning token billing
# Before (OpenAI)
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

# After (AssetMeld)
client = OpenAI(
    api_key=os.environ["ASSETMELD_API_KEY"],
    base_url="https://api.assetmeld.com/v1",
)

Privacy

AssetMeld does not store your prompts or completions.

Do not send secrets, passwords, private keys, or regulated data unless your use case explicitly allows it.

Security Best Practices

  • Keep API keys server-side — never expose in frontend code
  • Use environment variables, not hard-coded keys
  • Rotate keys periodically and after any suspected leak
  • Use separate keys for development and production
  • Validate tool arguments before executing them — model output is untrusted
  • Set request timeouts appropriate for your use case
  • Log request IDs for audit trails
  • Do not log sensitive prompts

Production Best Practices

  • Implement exponential backoff with jitter for retries
  • Retry only retryable errors (429, 500, 502, 503, 504)
  • Log request IDs, model, status, latency, and cost
  • Monitor latency, failure rate, and spend
  • Handle model deprecation gracefully — check the model catalog regularly
  • Add application-level budget limits
  • Set client-side and server-side timeouts

Parameter Compatibility

Feature availability varies by model. Check the model catalog for capability badges.

FeatureChatResponsesNotes
Text input✅✅
Streaming✅✅SSE compatible
Tools✅✅Model-dependent
Vision✅✅Model-dependent
JSON output✅✅Model-dependent
ReasoningPartial✅Model-dependent
Audio❌❌Not supported

Timeouts & Concurrency

  • Request timeout: requests may run for up to 600 seconds
  • Streaming timeout: idle streaming connections are closed after inactivity
  • Concurrent requests: limited per API key and per account
  • When concurrency is exceeded, the API returns 429

Cost Calculation

Each request shows a breakdown in the usage dashboard. Here is how cost is calculated:

Input:  1,000 tokens x $2.00 / 1M = $0.002
Output:   500 tokens x $8.00 / 1M = $0.004
Total:                     $0.006

The exact prices per model are shown on the Models page.

HTTP Headers

Request headers

HeaderRequiredDescription
AuthorizationYesBearer am_live_...
Content-TypeYesapplication/json

Response headers

HeaderDescription
X-Request-IDUnique request ID for support/debug
Retry-AfterSeconds to wait (on 429)

Model IDs

  • Model IDs are case-sensitive
  • IDs are stable but may be deprecated with advance notice
  • Always use the exact ID from the model catalog

Model lifecycle

  • Active: fully supported
  • Deprecated: still available but may be removed
  • Unavailable: temporarily or permanently offline

Reasoning Models

Some models support extended reasoning. Reasoning tokens are billed as output tokens. Reasoning content may be exposed as reasoning_content in the response.

Troubleshooting

ErrorCauseFix
401Wrong/revoked keyCheck key in dashboard
402Insufficient balanceAdd balance via billing
429Rate limitBack off, reduce concurrency
502Provider errorRetry with backoff
504TimeoutRetry, shorter prompts

Deprecation Policy

Breaking removals and model retirements are announced at least 7 days in advance when practical.

Status

Check system status at assetmeld.com/status.

Support

For account issues, billing questions, or failed requests, contact AssetMeld via Telegram (link in your dashboard). Include your account email and request ID when reporting a problem.