API Reference
Complete API documentation for programmatic access to attest.ink services
Table of Contents
Authentication
Most endpoints are publicly accessible. Premium features require an API key:
# Premium endpoints require API key
curl -X POST https://attest.ink/api/shorten \
-H "Content-Type: application/json" \
-d '{"apiKey": "ak_your_api_key", ...}'
💡 Getting an API Key: Purchase lifetime access for $20 to receive your API key via email.
Endpoints
Create Attestation
Create a new AI attestation for your content.
GET
/api/create.html
Parameters
Parameter | Type | Required | Description |
---|---|---|---|
content_name | string | Yes | Human-readable name for the content |
content | string | No | The actual content (will be hashed) |
content_hash | string | No | Pre-computed SHA-256 hash (format: sha256:... ) |
model | string | No | AI model ID (default: gpt-4 ) |
role | string | No | AI role: generated , assisted , or edited (default: assisted ) |
document_type | string | No | Content type (default: text ) |
author | string | No | Human author name |
prompt | string | No | The prompt used |
prompt_private | boolean | No | If true, only prompt hash is stored |
output | string | No | Response format: json or curl (default: json ) |
Example Request
curl -s "https://attest.ink/api/create.html?content_name=My%20Article&model=claude-3-opus&role=assisted&output=json"
Example Response (JSON)
{
"version": "2.0",
"id": "2025-08-05-abc123",
"content_name": "My Article",
"model": "claude-3-opus",
"role": "assisted",
"timestamp": "2025-08-05T10:30:00Z",
"platform": "attest.ink",
"dataUrl": "data:application/json;base64,eyJ2ZXJzaW9uIjoiMi4wIi...",
"verifyUrl": "https://attest.ink/verify/?data=eyJ2ZXJzaW9uIjoiMi4wIi...",
"badgeUrl": "https://attest.ink/assets/badges/claude-assisted.svg"
}
Example Response (curl format)
# Badge HTML
<a href="https://attest.ink/verify/?data=..." target="_blank">
<img src="https://attest.ink/assets/badges/claude-assisted.svg" alt="AI Assisted">
</a>
# Markdown
[](https://attest.ink/verify/?data=...)
Shorten URL
Create a permanent short URL for an attestation (Premium feature).
POST
/api/shorten
Headers
Content-Type: application/json
Request Body
Parameter | Type | Required | Description |
---|---|---|---|
dataUrl | string | Yes* | The attestation data URL |
url | string | Yes* | The attestation verify URL |
apiKey | string | Yes** | API key for permanent URLs |
string | Yes** | Email associated with API key |
*Either dataUrl
or url
is required
**Either apiKey
or email
is required
Example Request
curl -X POST https://attest.ink/api/shorten \
-H "Content-Type: application/json" \
-d '{
"dataUrl": "data:application/json;base64,eyJ2ZXJzaW9uIjoiMi4wIi4uLg==",
"apiKey": "ak_1234567890abcdef"
}'
Example Response
{
"shortUrl": "https://attest.ink/s/abc123",
"shortId": "abc123",
"expiresAt": null
}
Verify Attestation
Programmatically verify an attestation.
POST
/api/verify
Request Body
{
"attestation": {
"version": "2.0",
"id": "2025-08-05-abc123",
"content_name": "My Article",
"content_hash": "sha256:...",
"signature": {...}
},
"content": "Optional: original content for hash verification"
}
Example Response
{
"valid": true,
"checks": {
"format": true,
"version": true,
"required_fields": true,
"content_hash": true,
"signature": true
},
"errors": [],
"warnings": []
}
Get AI Models
Retrieve the list of supported AI models.
GET
/api/ai-models
Example Request
curl -s https://attest.ink/api/ai-models
Example Response
{
"success": true,
"models": {
"openai": {
"name": "OpenAI",
"models": [
{
"id": "gpt-5",
"name": "GPT-5 (Coming Soon)",
"color": "#74aa9c"
},
{
"id": "gpt-4-turbo-2024-04-09",
"name": "GPT-4 Turbo (Apr 2024)",
"color": "#74aa9c"
}
]
},
"anthropic": {
"name": "Anthropic",
"models": [
{
"id": "claude-4.1-opus",
"name": "Claude 4.1 Opus",
"color": "#d4a373"
}
]
}
},
"lastUpdated": "2025-08-05T10:30:00Z"
}
Response Formats
Standard Success Response
{
"success": true,
"data": {...},
"message": "Operation completed successfully"
}
Standard Error Response
{
"success": false,
"error": "Error message",
"code": "ERROR_CODE",
"details": {...}
}
Error Handling
HTTP Status Codes
Code | Description |
---|---|
200 | Success |
400 | Bad Request - Invalid parameters |
403 | Forbidden - Payment required or invalid API key |
404 | Not Found - Resource doesn't exist |
405 | Method Not Allowed |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error |
Error Codes
Code | Description |
---|---|
INVALID_PARAMS | Missing or invalid parameters |
PAYMENT_REQUIRED | Premium feature requires payment |
INVALID_API_KEY | API key is invalid or expired |
RATE_LIMIT | Rate limit exceeded |
INVALID_CONTENT | Content validation failed |
Rate Limits
- Public endpoints: 100 requests per minute per IP
- Authenticated endpoints: 1000 requests per minute per API key
- Burst allowance: 10x rate for 10 seconds
Rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1628089200
Code Examples
JavaScript/Node.js
const axios = require('axios');
async function createAttestation(contentName, model = 'gpt-4') {
const params = new URLSearchParams({
content_name: contentName,
model: model,
role: 'assisted',
output: 'json'
});
const response = await axios.get(`https://attest.ink/api/create.html?${params}`);
return response.data;
}
async function shortenUrl(dataUrl, apiKey) {
const response = await axios.post('https://attest.ink/api/shorten', {
dataUrl: dataUrl,
apiKey: apiKey
});
return response.data.shortUrl;
}
// Usage
(async () => {
const attestation = await createAttestation('My Project', 'claude-3-opus');
console.log('Verification URL:', attestation.verifyUrl);
if (process.env.ATTEST_INK_API_KEY) {
const shortUrl = await shortenUrl(attestation.dataUrl, process.env.ATTEST_INK_API_KEY);
console.log('Short URL:', shortUrl);
}
})();
Python
import requests
import json
from urllib.parse import urlencode
def create_attestation(content_name, model='gpt-4', role='assisted'):
"""Create an AI attestation"""
params = {
'content_name': content_name,
'model': model,
'role': role,
'output': 'json'
}
response = requests.get(
'https://attest.ink/api/create.html',
params=params
)
response.raise_for_status()
return response.json()
def shorten_url(data_url, api_key):
"""Create a short URL for an attestation"""
response = requests.post(
'https://attest.ink/api/shorten',
json={
'dataUrl': data_url,
'apiKey': api_key
}
)
response.raise_for_status()
return response.json()['shortUrl']
# Usage
if __name__ == '__main__':
# Create attestation
attestation = create_attestation('My Python Project', 'github-copilot')
print(f"Verification URL: {attestation['verifyUrl']}")
# Create short URL if API key is available
import os
if api_key := os.getenv('ATTEST_INK_API_KEY'):
short_url = shorten_url(attestation['dataUrl'], api_key)
print(f"Short URL: {short_url}")
PHP
<?php
function createAttestation($contentName, $model = 'gpt-4', $role = 'assisted') {
$params = http_build_query([
'content_name' => $contentName,
'model' => $model,
'role' => $role,
'output' => 'json'
]);
$url = "https://attest.ink/api/create.html?{$params}";
$response = file_get_contents($url);
return json_decode($response, true);
}
function shortenUrl($dataUrl, $apiKey) {
$data = json_encode([
'dataUrl' => $dataUrl,
'apiKey' => $apiKey
]);
$options = [
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $data
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://attest.ink/api/shorten', false, $context);
$result = json_decode($response, true);
return $result['shortUrl'];
}
// Usage
$attestation = createAttestation('My PHP Project', 'gpt-4');
echo "Verification URL: {$attestation['verifyUrl']}\n";
if ($apiKey = getenv('ATTEST_INK_API_KEY')) {
$shortUrl = shortenUrl($attestation['dataUrl'], $apiKey);
echo "Short URL: {$shortUrl}\n";
}
?>
Ruby
require 'net/http'
require 'json'
require 'uri'
def create_attestation(content_name, model: 'gpt-4', role: 'assisted')
uri = URI('https://attest.ink/api/create.html')
uri.query = URI.encode_www_form(
content_name: content_name,
model: model,
role: role,
output: 'json'
)
response = Net::HTTP.get_response(uri)
JSON.parse(response.body)
end
def shorten_url(data_url, api_key)
uri = URI('https://attest.ink/api/shorten')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = {
dataUrl: data_url,
apiKey: api_key
}.to_json
response = http.request(request)
JSON.parse(response.body)['shortUrl']
end
# Usage
attestation = create_attestation('My Ruby Project', model: 'github-copilot')
puts "Verification URL: #{attestation['verifyUrl']}"
if api_key = ENV['ATTEST_INK_API_KEY']
short_url = shorten_url(attestation['dataUrl'], api_key)
puts "Short URL: #{short_url}"
end
Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"os"
)
type Attestation struct {
Version string `json:"version"`
ID string `json:"id"`
DataURL string `json:"dataUrl"`
VerifyURL string `json:"verifyUrl"`
}
type ShortenResponse struct {
ShortURL string `json:"shortUrl"`
ShortID string `json:"shortId"`
}
func createAttestation(contentName, model string) (*Attestation, error) {
params := url.Values{}
params.Add("content_name", contentName)
params.Add("model", model)
params.Add("role", "assisted")
params.Add("output", "json")
resp, err := http.Get("https://attest.ink/api/create.html?" + params.Encode())
if err != nil {
return nil, err
}
defer resp.Body.Close()
var attestation Attestation
if err := json.NewDecoder(resp.Body).Decode(&attestation); err != nil {
return nil, err
}
return &attestation, nil
}
func shortenURL(dataURL, apiKey string) (string, error) {
payload := map[string]string{
"dataUrl": dataURL,
"apiKey": apiKey,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return "", err
}
resp, err := http.Post(
"https://attest.ink/api/shorten",
"application/json",
bytes.NewBuffer(jsonData),
)
if err != nil {
return "", err
}
defer resp.Body.Close()
var result ShortenResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", err
}
return result.ShortURL, nil
}
func main() {
attestation, err := createAttestation("My Go Project", "github-copilot")
if err != nil {
panic(err)
}
fmt.Printf("Verification URL: %s\n", attestation.VerifyURL)
if apiKey := os.Getenv("ATTEST_INK_API_KEY"); apiKey != "" {
shortURL, err := shortenURL(attestation.DataURL, apiKey)
if err != nil {
panic(err)
}
fmt.Printf("Short URL: %s\n", shortURL)
}
}
Webhooks (Coming Soon)
Future support for webhooks to notify your application of events:
- Attestation created
- Attestation verified
- Short URL accessed
Support
- Documentation: attest.ink/docs
- GitHub Issues: Report bugs or request features
- Email: api@attest.ink
Last updated: August 2025