Skip to main content
The Everhour API uses standard HTTP status codes. All error responses include a JSON body with a code and message field.

Error response format

{
  "code": 404,
  "message": "Resource not found"
}
Some errors include an additional errors field with per-field validation details:
{
  "code": 422,
  "message": "Validation failed",
  "errors": {
    "time": ["must be a positive integer"]
  }
}

Status codes

CodeMeaning
200Success
201Resource created
204Success, no content returned
400Bad request — malformed JSON or missing required parameter
403Forbidden — missing or invalid API key, or your account lacks permission for this action
404Not found — resource does not exist or is not accessible to your account
422Unprocessable entity — request was valid JSON but failed validation
429Too many requests — rate limit exceeded. See Rate limits
503Service unavailable — something went wrong on our end

Handling errors

Check the HTTP status code before parsing the response body. A 2xx status indicates success. For anything else, read the message field for a human-readable explanation.
response=$(curl -s -w "\n%{http_code}" https://api.everhour.com/projects \
  -H "X-Api-Key: YOUR_API_KEY")
body=$(echo "$response" | head -1)
status=$(echo "$response" | tail -1)
if [ "$status" -ge 400 ]; then
  echo "Error: $body"
fi
require "net/http"
require "json"

uri = URI("https://api.everhour.com/projects")
req = Net::HTTP::Get.new(uri, { "X-Api-Key" => "YOUR_API_KEY" })
resp = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
unless resp.is_a?(Net::HTTPSuccess)
  error = JSON.parse(resp.body)
  puts "Error #{error['code']}: #{error['message']}"
end
import requests

response = requests.get(
    "https://api.everhour.com/projects",
    headers={"X-Api-Key": "YOUR_API_KEY"}
)
if not response.ok:
    error = response.json()
    print(f"Error {error['code']}: {error['message']}")
$ch = curl_init("https://api.everhour.com/projects");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["X-Api-Key: YOUR_API_KEY"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
    $error = json_decode($body, true);
    echo "Error {$error['code']}: {$error['message']}";
}
import java.net.URI;
import java.net.http.*;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.everhour.com/projects"))
    .header("X-Api-Key", "YOUR_API_KEY")
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
    System.out.println("Error: " + response.body());
}
const response = await fetch("https://api.everhour.com/projects", {
  headers: { "X-Api-Key": "YOUR_API_KEY" }
});
if (!response.ok) {
  const error = await response.json();
  console.error(`Error ${error.code}: ${error.message}`);
}
// import "fmt"; "io"; "net/http"
req, _ := http.NewRequest("GET", "https://api.everhour.com/projects", nil)
req.Header.Set("X-Api-Key", "YOUR_API_KEY")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
if resp.StatusCode >= 400 {
    body, _ := io.ReadAll(resp.Body)
    fmt.Printf("Error: %s\n", body)
}
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-Api-Key", "YOUR_API_KEY");
var response = await client.GetAsync("https://api.everhour.com/projects");
if (!response.IsSuccessStatusCode) {
    var body = await response.Content.ReadAsStringAsync();
    Console.WriteLine($"Error: {body}");
}
If you encounter a 503 error that persists, contact support via chat inside your Everhour account or at ask@everhour.com with the request details.