L402
How to use it as an API
Understanding L402: Pay-Per-Use APIs with Bitcoin 💡
L402 is a "Bitcoin Standard" for APIs. It lets different applications "talk" to each other securely. Instead of usernames, passwords, and credit card details, it uses a clever combination of:
- Macaroons: These are like special, tamper-proof digital "tickets" or "tokens" that grant access.
- Lightning Network: This allows for instant, low-fee Bitcoin payments.
Together, they create a secure and private way to access paid services. You only pay for what you use.Learn More
Choose a service to get started:
How to Use Our L402 Services: A Step-by-Step Guide ⚙️
Using an L402-protected service involves a simple two-step process: first, you request access and get a "bill" (invoice), and second, you pay the bill and present your "proof of payment" (preimage) to use the service.
Step 1: Request Access & Get Your "Ticket" and "Invoice"
- Make Your First Request: Send your initial API request to the desired service endpoint.
- Receive a
402 Payment Required
Response: This is normal! The response header will contain:- A Macaroon (your access "ticket").
- An Invoice (a Lightning Network payment request).
www-authenticate: L402 macaroon="<YOUR_UNIQUE_MACAROON>", invoice="<LIGHTNING_INVOICE_STRING>"
Step 2: Pay the Invoice & Use the Service
- Pay the Lightning Invoice: Use any Lightning-compatible wallet.
- Get the Preimage: After payment, your wallet provides a preimage (your "proof of payment").
- Make Your Second Request (with Payment Proof): Send the exact same request as in Step 1 tohttps://sats4ai.com/api/l402/text-generation. This time, include the `Authorization` header:
Authorization: L402 <YOUR_UNIQUE_MACAROON>:<YOUR_PREIMAGE>
❗ Important Notes:
- Identical Requests: The body/data of your first and second requests must be exactly the same.
- Not a Stream (Currently): Our L402 services do not currently support streaming responses.
Using the L402 Text Generation API
You can generate text responses by sending a POST request to our L402-protected text generation endpoint. This API supports conversational context. Follow the steps below, which include example `curl` commands.
API Endpoint: https://sats4ai.com/api/l402/text-generation
Step 1: Initial Request (to get Macaroon and Invoice)
First, make a request to the API with your text generation parameters, including the conversation history if any. This initial request will not generate the text yet; instead, it will return a 402 Payment Required
status along with the L402 headers (a macaroon and a Lightning invoice).
Example `curl` command:
curl -X POST https://sats4ai.com/api/l402/text-generation \
-H "Content-Type: application/json" \
-d '{"input":[{"role":"User","content":"Tell me a story of a bird"},{"role":"Assistant","content":"Once upon a time, there was a little bird who loved to sing..."},{"role":"User","content":"What happened next?"}],"model":"Best"}' \
-i
Explanation of the command:
-X POST
: Specifies an HTTP POST request.https://sats4ai.com/api/l402/text-generation
: The target API URL.-H "Content-Type: application/json"
: Indicates the request body is JSON.-d '{...}'
: The JSON data payload with your text generation preferences (see "Request Body Parameters" below for details).-i
: Tells `curl` to include HTTP response headers in the output.
Expected Response Headers:
You will receive an HTTP/1.1 402 Payment Required
response. Look for the www-authenticate
header:
www-authenticate: L402 macaroon="<YOUR_MACAROON_STRING_HERE>", invoice="<YOUR_LIGHTNING_INVOICE_HERE>"
<YOUR_MACAROON_STRING_HERE>
: Your unique access token.<YOUR_LIGHTNING_INVOICE_HERE>
: The Lightning Network invoice to pay.
Step 2: Pay the Lightning Invoice
Copy the <YOUR_LIGHTNING_INVOICE_HERE>
string and pay it using any Lightning-enabled Bitcoin wallet. Upon successful payment, your wallet will provide you with a preimage (your proof of payment).
Step 3: Final Request (to get the Text Response)
Once you have the macaroon (from Step 1) and the preimage (from Step 2), make the exact same POST request again. This time, include an Authorization
header.
Important: The JSON data payload (-d '{...}'
) in this second request must be identical to the one sent in Step 1.
Example `curl` command:
curl -X POST https://sats4ai.com/api/l402/text-generation \
-H "Content-Type: application/json" \
-H "Authorization: L402 <YOUR_MACAROON_STRING_HERE>:<YOUR_PREIMAGE_HERE>" \
-d '{"input":[{"role":"User","content":"Tell me a story of a bird"},{"role":"Assistant","content":"Once upon a time, there was a little bird who loved to sing..."},{"role":"User","content":"What happened next?"}],"model":"Best"}'
Explanation of changes:
- Replace
<YOUR_MACAROON_STRING_HERE>
with the macaroon from Step 1. - Replace
<YOUR_PREIMAGE_HERE>
with the preimage from Step 2. - The
-H "Authorization: L402 <macaroon>:<preimage>"
header is added.
Expected Successful Response:
If the L402 authentication is valid, the API will process your request and return the AI model's text response directly in the response body (typically as a JSON string or plain text, depending on your API's specific output for this endpoint). For instance, it might be a JSON object like:
The little bird soared higher, discovering a hidden valley full of musical flowers.
Request Body Parameters
The POST request body should be a JSON object with the following structure:
{
"input": [
{
"role": "User",
"content": "Tell me a story of a bird"
},
{
"role": "Assistant",
"content": "Once upon a time, there was a little bird who loved to sing..."
},
{
"role": "User",
"content": "What happened next?"
}
],
"model": "Best"
}
model
: string
The quality of the model used for inference.
Accepted Values: "Standard"
, "Best"
Example: "Best"
input
: array of objects
The input
array contains objects representing the conversation history. Each object must have a role
and content
field. The order of messages should reflect the flow of conversation.
Object structure within input
array:
role
: string
Indicates who sent the message.
Accepted Values: "User"
, "Assistant"
content
: string
The actual text content of the message.
Example:
{
"role": "User",
"content": "Tell me a story of a bird"
}