Authentication
Learn how to authenticate your requests using API keys and manage your access credentials.
API Key Authentication
Authentication Required
All StayAPI endpoints require authentication using an API key.
StayAPI uses API key authentication for all requests. You must include your API key in the x-api-key
header with every API request.
How to Include Your API Key
Add the x-api-key
header to every request:
x-api-key: YOUR_API_KEY_HERE
Getting Your API Key
Sign Up for an Account
Create a free StayAPI account to get started. No credit card required for testing.
Sign Up for Free →Access Your Dashboard
Once logged in, navigate to your dashboard to view and manage your API keys.
Generate API Key
Generate a new API key for your application. You can create multiple keys for different environments.
API Key Security
Keep Your API Key Secure
Never expose your API key in client-side code, public repositories, or unsecured environments.
Best Practices
- Store API keys as environment variables
- Use different keys for development, staging, and production
- Rotate your API keys regularly
- Never commit API keys to version control
- Use server-side requests only - never expose keys in client-side code
Environment Variables Example
# .env file STAYAPI_KEY=your_api_key_here # In your application api_key = process.env.STAYAPI_KEY # Node.js api_key = os.environ['STAYAPI_KEY'] # Python api_key = ENV['STAYAPI_KEY'] # Ruby
Rate Limits
API keys are subject to rate limits to ensure fair usage and optimal performance for all users.
Plan | Requests per Hour | Requests per Day |
---|---|---|
Free | 100 | 1,000 |
Professional | 1,000 | 25,000 |
Enterprise | Custom | Custom |
Rate Limit Headers
Check the response headers for rate limit information: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
Authentication Errors
401 Unauthorized
Returned when no API key is provided or the API key is invalid.
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key", "details": "Please provide a valid API key in the x-api-key header" } }
429 Rate Limit Exceeded
Returned when you exceed your rate limit.
{ "error": { "code": "rate_limit_exceeded", "message": "Rate limit exceeded", "details": "You have exceeded your hourly rate limit. Try again later." } }
curl -X GET "https://api.stayapi.com/v1/meta/search" \ -H "x-api-key: sk_live_abcd1234..." \ -H "Content-Type: application/json" \ -G \ -d "hotel_name=Four Seasons Resort Bali"
const response = await fetch("https://api.stayapi.com/v1/meta/search", { headers: { "x-api-key": process.env.STAYAPI_KEY, // Use environment variable "Content-Type": "application/json" } }); if (response.status === 401) { console.error("Invalid API key"); } else if (response.status === 429) { console.error("Rate limit exceeded"); console.log("Rate limit resets at:", response.headers.get("X-RateLimit-Reset")); } else if (response.ok) { const data = await response.json(); console.log("Success:", data); }
import requests import os headers = { "x-api-key": os.environ["STAYAPI_KEY"], # Use environment variable "Content-Type": "application/json" } response = requests.get( "https://api.stayapi.com/v1/meta/search", headers=headers, params={"hotel_name": "Four Seasons Resort Bali"} ) if response.status_code == 401: print("Invalid API key") elif response.status_code == 429: print("Rate limit exceeded") print(f"Limit: {response.headers.get(\"X-RateLimit-Limit\")}") print(f"Remaining: {response.headers.get(\"X-RateLimit-Remaining\")}") elif response.status_code == 200: data = response.json() print(f"Success: Found {len(data[\"data\"][\"links\"])} platforms")
<?php $headers = [ "x-api-key: " . $_ENV["STAYAPI_KEY"], // Use environment variable "Content-Type: application/json" ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.stayapi.com/v1/meta/search?hotel_name=Four%20Seasons%20Resort%20Bali"); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); switch ($httpCode) { case 401: echo "Invalid API key\n"; break; case 429: echo "Rate limit exceeded\n"; break; case 200: $data = json_decode($response, true); echo "Success: Found " . count($data["data"]["links"]) . " platforms\n"; break; default: echo "Error: HTTP $httpCode\n"; } ?>
require "net/http" require "uri" require "json" uri = URI("https://api.stayapi.com/v1/meta/search") uri.query = URI.encode_www_form({hotel_name: "Four Seasons Resort Bali"}) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["x-api-key"] = ENV["STAYAPI_KEY"] # Use environment variable request["Content-Type"] = "application/json" response = http.request(request) case response.code when "401" puts "Invalid API key" when "429" puts "Rate limit exceeded" puts "Limit: #{response[\"X-RateLimit-Limit\"]}" puts "Remaining: #{response[\"X-RateLimit-Remaining\"]}" when "200" data = JSON.parse(response.body) puts "Success: Found #{data[\"data\"][\"links\"].length} platforms" else puts "Error: #{response.code}" end
{ "status": "success", "data": { "hotel_name": "Four Seasons Resort Bali", "links": { "booking_com": "https://www.booking.com/hotel/id/four-seasons-resort-bali-at-jimbaran-bay.html", "expedia": "https://www.expedia.com/Jimbaran-Hotels-Four-Seasons-Resort-Bali.h1234567.Hotel-Information", "hotels_com": "https://hotels.com/ho123456/four-seasons-resort-bali-jimbaran-indonesia/", "agoda": "https://www.agoda.com/four-seasons-resort-bali-at-jimbaran-bay/hotel/bali-id.html" }, "platform_count": 4, "official_website_detected": true } }
{ "error": { "code": "unauthorized", "message": "Invalid or missing API key", "details": "Please provide a valid API key in the x-api-key header" } }