API Reference
SwiftGuard analyzes Swift source code for concurrency bugs, Sendable violations, and common pitfalls using AST parsing. All responses are JSON.
Authentication
Pass your API key in the Authorization header. For testing, use the demo key.
Authorization: Bearer sg_demo_key_2026
The demo key is rate-limited to 100 requests/minute. Authentication is optional for the live demo on the landing page.
Endpoint
/api/v1/reviewRequest Body
{
"source": "let x: String? = nil\nlet y = x!",
"swiftVersion": "6.0", // optional
"platform": "ios" // optional
}source (required) — Swift source code as a string.
swiftVersion (optional) — Target Swift version. Default: latest.
platform (optional) — Target platform (ios, macos, server). For future use.
Response Format
{
"issues": [
{
"rule": "force-unwrap",
"severity": "warning",
"message": "Force unwrap operator used. This will crash at runtime if the value is nil.",
"line": 2,
"column": 12,
"confidence": 0.95,
"suggestion": "Use optional binding (if let/guard let) or the nil-coalescing operator (??) instead."
}
],
"metadata": {
"rulesApplied": 7,
"parseTimeMs": 3,
"astValid": true
}
}issues[] — Array of detected problems.
issues[].rule — Rule identifier.
issues[].severity — "error" | "warning" | "info"
issues[].confidence — 0.0 to 1.0. Higher means more certain.
issues[].suggestion — Recommended fix.
metadata.rulesApplied — Number of rules evaluated.
metadata.parseTimeMs — Parse time in milliseconds.
metadata.astValid — Whether the AST parsed without errors.
Rules Reference
| Rule ID | Severity | Confidence | Description |
|---|---|---|---|
| force-unwrap | warning | 0.50–0.95 | Detects force unwrap operator (!) usage that can cause runtime crashes |
| unsafe-unchecked-sendable | warning | 0.85–0.90 | Flags @unchecked Sendable conformance on types with mutable stored properties |
| actor-isolation-violation | error | 0.85–0.95 | Detects cross-isolation access to actor state from non-async or detached contexts |
| non-sendable-boundary-crossing | warning | 0.80–0.95 | Non-Sendable types captured or passed across concurrency boundaries |
| task-data-race-risk | error | 0.88–0.92 | Shared mutable state accessed or mutated inside Task closures |
| missing-sendable-closure | warning | 0.85 | Closure/function types in actors or Sendable contexts missing @Sendable |
| missing-sendable-conformance | info | 0.75 | Types used as actor method parameters without Sendable conformance |
Code Examples
curl
curl -X POST https://your-domain.com/api/v1/review \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sg_demo_key_2026" \
-d '{"source": "let x: String? = nil\nlet y = x!"}'Swift (URLSession)
import Foundation
let url = URL(string: "https://your-domain.com/api/v1/review")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer sg_demo_key_2026", forHTTPHeaderField: "Authorization")
let body: [String: Any] = [
"source": "let x: String? = nil\nlet y = x!",
"swiftVersion": "6.0"
]
request.httpBody = try JSONSerialization.data(withJSONObject: body)
let (data, _) = try await URLSession.shared.data(for: request)
let result = try JSONDecoder().decode(ReviewResponse.self, from: data)
print("Found \(result.issues.count) issues")Python (requests)
import requests
response = requests.post(
"https://your-domain.com/api/v1/review",
headers={
"Authorization": "Bearer sg_demo_key_2026",
"Content-Type": "application/json",
},
json={
"source": "let x: String? = nil\nlet y = x!",
"swiftVersion": "6.0",
},
)
data = response.json()
for issue in data["issues"]:
print(f"[{issue['severity']}] {issue['rule']}: {issue['message']}")Rate Limits
To keep the service reliable for everyone, the API is rate-limited to 100 requests per minute.
When rate limited, the API returns HTTP 429 with a JSON error body.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid JSON body or missing source field |
| 401 | Invalid or malformed API key |
| 429 | Rate limit exceeded (100 req/min) |