Install
openclaw skills install @assareh/ask-milesAsk Miles (askmiles.ai) card and points questions against the owner's real wallet: which card to get next, keep-or-cancel math, transfer partners and ratios, award strategy, and which card to use for a purchase. Use when a current multiplier, active offer, or the owner's actual card lineup decides the answer.
openclaw skills install @assareh/ask-milesLast updated 2026-09-11 — the latest version of this file lives at https://askmiles.ai/skills/ask-miles.md; re-fetch it to upgrade.
Miles is a credit card rewards engine. Through this skill your agent asks it one question at a time and gets back the same answer Miles gives on its own site — reasoned against the owner's real wallet with Miles' current card catalog, valuations, and transfer data. Miles does the reasoning on its side; you spend one tool call, not forty-six.
OpenAI-compatible chat completions:
POST https://askmiles.ai/v1/chat/completions
Authorization: Bearer <credential>
{"model": "miles", "messages": [{"role": "user", "content": "<question>"}]}
miles — the only one.Python-urllib User-Agent gets an opaque Cloudflare
403, not an API error.miles object with tools_called and
duration_ms. Read it — see Provenance below.Two credentials reach this endpoint. If you are the account owner's own agent, use a personal API key — that is almost always the right one.
Ask the owner to mint one at https://askmiles.ai/settings?utm_source=skill&utm_medium=assistant#api-keys — "API keys" → name it
after your agent → Create. It is shown once, looks like miles_sk_…, and
is pasted straight into any OpenAI-compatible client:
from openai import OpenAI
client = OpenAI(base_url="https://askmiles.ai/v1", api_key="miles_sk_…")
No browser dance, no registration, no refresh loop. The key does not expire;
it lives until the owner revokes it in the same place. Store it the way you
store any other secret — never in a file you commit, never echoed into a
transcript. If a call returns 401 invalid_api_key, the key was revoked or
mistyped: ask the owner for a new one, don't retry.
If the owner has Connected AI Apps paused, creating a key is refused and an
existing key gets 403 connections_paused — the fix is theirs to make in
Settings, not something to retry around.
Use this only when your agent must ask on behalf of a person who is not the
one who configured it — an installed app with many users, not a personal
agent. OAuth 2.1 against mcp.askmiles.ai, scope miles:chat, with dynamic
client registration. The grant belongs to the Miles account of the person who
approves it, and requires a one-time browser consent. Access tokens expire
after one hour — store the refresh token and refresh.
Getting a token — follow this recipe, don't improvise. In particular, do
NOT register mcp.askmiles.ai as an MCP server (claude mcp add, MCP
connectors): that is a different integration — it grants MCP tool scopes and
stores its token where your HTTP calls can't reach it, and it never produces
a token this endpoint accepts.
https://mcp.askmiles.ai/.well-known/oauth-authorization-server for the
authorization, token, and registration endpoints. Every URL below comes
from this document.client_name naming your agent,
redirect_uris: ["http://127.0.0.1:<your port>/callback"] (loopback
HTTP is supported per RFC 8252 — pick any free port),
grant_types: ["authorization_code", "refresh_token"],
response_types: ["code"],
token_endpoint_auth_method: "client_secret_post", and
scope: "miles:chat". Store the returned client_id and
client_secret — they are reused for every refresh.code_verifier and its S256
code_challenge, plus a state value, and listen once on your loopback
port.response_type=code, your client_id and
redirect_uri, scope=miles:chat, state, code_challenge, and
code_challenge_method=S256. They approve in a browser where they are
signed in to askmiles.ai; the redirect hands your listener code and
state. Reject a state that doesn't match yours.grant_type=authorization_code, the code, the same redirect_uri,
client_id, client_secret, code_verifier. The response carries the
Bearer access_token (one hour), scope: miles:chat, and a
refresh_token.grant_type=refresh_token and your stored
credentials. The browser step never repeats unless the owner revokes the
grant (Settings → Connected AI Apps on askmiles.ai).Either credential is one person's identity. Answers come from that person's wallet and spend that person's usage allowance. If your agent serves a household, only route the account owner's questions here; for anyone else, say a separate Miles account is needed rather than answering from the wrong wallet.
Send the user's question verbatim by default. Rewording a question that already stands alone changes what gets asked, for no gain. Compose your own question only when you must:
Follow-ups: replay your own history. Miles keeps no conversation state —
each request stands alone — but the endpoint accepts OpenAI-style history.
Send your prior Q/A exchanges with Miles as user/assistant message pairs
ahead of the new question, and a follow-up like "why not the Venture X?"
works verbatim. History is truncated server-side to the last 26 messages;
in practice, replay the last ~5 exchanges and drop history that is more than
a session old, so a fresh question doesn't drag last week's thread along.
Don't send a system message. Miles demotes caller system messages to
data and never follows them. You cannot set its persona or framing; say what
you need in the user turn.
Miles' answer is tool output, not your reply. Write your own reply from it:
miles.tools_called is empty, Miles answered from
the model's own knowledge, not its catalog. Treat that answer as unverified
and say so if you relay it.A 429 (limits: 30 requests/minute and 2 concurrent turns — counted per OAuth
grant, and once per account across every personal API key it holds; honor
Retry-After), a timeout, or a network error is not Miles saying no.
Never let an outage read as "that card doesn't exist" or "there's no better
option." Say Miles couldn't be reached, answer from whatever local data you
trust, and name which source you used.
Chat is read-only, always — nothing you send can change the wallet, whatever scopes the token holds. It sees the owner's wallet and Miles' own catalog, valuations, and guides; it cannot see anything else about the person, and nothing you send is used to change their account.