> ## Documentation Index
> Fetch the complete documentation index at: https://grat.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API

> Integrate Grat from any language using standard HTTP requests.

Grat's relay is a standard REST API. Any programming language that can make HTTP requests can integrate directly with Grat. No dedicated SDK is required to start sponsoring transactions.

### Sponsoring a Transaction

To sponsor a transaction, send a POST request to the `/v1/sponsor` endpoint with the base64-encoded XDR.

```bash theme={null}
curl -X POST http://localhost:3000/v1/sponsor \
  -H "Content-Type: application/json" \
  -d '{
    "transaction": "AAAAAgAAAA...",
    "network": "testnet"
  }'
```

### Language Examples

<CodeGroup>
  ```python Python theme={null}
  import requests

  def sponsor_tx(xdr):
      url = "http://localhost:3000/v1/sponsor"
      payload = {
          "transaction": xdr,
          "network": "testnet"
      }
      response = requests.post(url, json=payload)
      
      if response.status_code == 200:
          return response.json()
      else:
          print(f"Error: {response.status_code}")
          return None
  ```

  ```go Go theme={null}
  package main

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

  func sponsorTx(xdr string) (*SponsorResponse, error) {
  	url := "http://localhost:3000/v1/sponsor"
  	payload := map[string]string{
  		"transaction": xdr,
  		"network":     "testnet",
  	}
  	body, _ := json.Marshal(payload)

  	resp, err := http.Post(url, "application/json", bytes.NewBuffer(body))
  	if err != nil {
  		return nil, err
  	}
  	defer resp.Body.Close()

  	var result SponsorResponse
  	json.NewDecoder(resp.Body).Decode(&result)
  	return &result, nil
  }
  ```

  ```rust Rust theme={null}
  use serde::{Deserialize, Serialize};

  #[derive(Serialize)]
  struct SponsorRequest {
      transaction: String,
      network: String,
  }

  async func sponsor_tx(xdr: String) -> Result<SponsorResponse, reqwest::Error> {
      let client = reqwest::Client::new();
      let res = client.post("http://localhost:3000/v1/sponsor")
          .json(&SponsorRequest {
              transaction: xdr,
              network: "testnet".to_string(),
          })
          .send()
          .await?;

      res.json::<SponsorResponse>().await
  }
  ```

  ```dart Dart theme={null}
  import 'package:http/http.dart' as http;
  import 'dart:convert';

  Future<Map<String, dynamic>> sponsorTx(String xdr) async {
    final url = Uri.parse('http://localhost:3000/v1/sponsor');
    final response = await http.post(
      url,
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({
        'transaction': xdr,
        'network': 'testnet',
      }),
    );

    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('Failed to sponsor transaction');
    }
  }
  ```
</CodeGroup>

### Endpoints Summary

| Endpoint       | Method | Description                          |
| :------------- | :----- | :----------------------------------- |
| `/v1/sponsor`  | `POST` | Wrap and submit a transaction.       |
| `/v1/simulate` | `POST` | Simulate a Soroban transaction.      |
| `/v1/estimate` | `POST` | Get fee estimates for a transaction. |
| `/health`      | `GET`  | Check relay health and status.       |

### Error Handling

When an error occurs, the API returns a JSON object with a standardized format.

```json theme={null}
{
  "error": {
    "code": "SUBMISSION_FAILED",
    "message": "Transaction Failed: tx_bad_seq",
    "details": { "result_codes": { "transaction": "tx_bad_seq" } },
    "requestId": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

### Retry Logic

If you are implementing your own integration, we recommend retrying requests that return the following status codes:

* **429 Too Many Requests**: Use the value in the `Retry-After` header.
* **503 Service Unavailable**: Use exponential backoff (e.g., 1s, 2s, 4s).

### Tips

* **Idempotency**: Use the `X-Idempotency-Key` header to safely retry requests without risk of double-submission.
* **Rate Limits**: Pay attention to rate limit headers in the response to avoid 429 errors.
* **Stroops**: All fee values in the API are represented in stroops (1 XLM = 10,000,000 stroops).

<Info>
  Do you need a dedicated SDK for your programming language? Open a feature request on our [GitHub repository](https://github.com/gratnetwork/grat).
</Info>

[View on GitHub](https://github.com/gratnetwork/grat)
