Base API Specification
Copy
Base URL: https://genacnh.com/api
Content-Type: application/x-www-form-urlencoded | application/json
Accept: application/json
Authentication Header
Provide your Bot Token (issued via Developer Portal ) in the HTTP request header:
Copy
X-Bot-Token: gen_bot_tok_1a2b3c4d5e6f7g8h9i0j...
Rate Limits & Imunify360 WAF
Recommended Polling & Heartbeat Frequencies
Endpoint Action Recommended Interval Hard Rate Limit
/v1/island/heartbeatEvery 20β30 seconds Max 1 request / 5 seconds
/v1/island/updateOn Dodo change / status toggle Max 1 request / 5 seconds
/v1/island/subscribersOn resident visitor join Max 60 requests / minute
π‘οΈ Imunify360 & Sentinel Integration : SysBot client requests include authorized User-Agent: SysBot.GenACNH/1.0 and X-Bot-Token headers to bypass web flood rate-limit triggers automatically.
HTTP Status Codes
Code Status Description
200OK Request processed successfully
400Bad Request Missing required parameters or invalid payload
401Unauthorized Missing or invalid X-Bot-Token header
500Internal Error Server execution exception
GET
/api/v1/public/active-hosts
β¨ No API Key Required
Ultra-Fast 15s Cached JSON
Designed specifically for third-party companion mobile apps (e.g., ACNH Guide , Horizon Pedia , Nookazon bots , Twitch overlays, and Discord bots). Query live, automated Animal Crossing: New Horizons treasure islands with real-time Dodo codes, queue capacity, and categories.
Query Parameters (Optional)
Parameter Type Default Description
categorystring allFilter by item theme: diys, materials, nookmiles, furniture, clothes, villagers, maxbells, all_items
typestring allfree (public free islands only), vip (subscription passes), or all
statusstring allopen (has available visitor slots < 7), full, or all
limitint 50Maximum number of hosts to return (1 to 100)
Response Schema (200 OK)
Copy
{
"success": true,
"api_version": "v1.0",
"total_active_hosts": 18,
"free_public_hosts": 14,
"filters": {
"category": "all",
"type": "all",
"status": "all",
"limit": 50
},
"hosts": [
{
"id": 14,
"name": "Starfall DIY Paradise",
"category": "diys",
"category_label": "All DIY Recipes & Crafting",
"description": "All 2.0 DIY recipes, golden tools, seasonal recipes, and crafting benches.",
"dodo_code": "8M2KP",
"is_free": true,
"status": "ONLINE",
"current_visitors": 3,
"max_visitors": 7,
"available_slots": 4,
"host": {
"username": "NookMaster",
"bot_name": "SysBot-Alpha",
"avatar_url": "https://genacnh.com/images/logo/GenACNH_Logo.png"
},
"uptime_minutes": 1420,
"last_heartbeat": "2026-08-23T20:45:00Z",
"web_url": "https://genacnh.com/islands.php"
}
],
"documentation": "https://genacnh.com/developer_docs.php#public-api",
"attribution": {
"name": "GenACNH",
"url": "https://genacnh.com/islands.php",
"notice": "Data provided by GenACNH Island Automation Network. Companion apps must link to https://genacnh.com/islands.php"
}
}
Companion App Developer Guidelines
Attribution & Integration Rules
Free Forever : This public directory endpoint is free to integrate into any iOS, Android, macOS, Windows, or web companion application.
CORS Enabled : Headers include Access-Control-Allow-Origin: * allowing direct client-side requests from React Native, Flutter, Swift, and web applications.
Attribution Requirement : When listing GenACNH islands in your companion app, provide a clickable button or label linking to https://genacnh.com/islands.php (e.g., "Powered by GenACNH" or "View on GenACNH" ).
Client Caching : We recommend caching results client-side for 15β30 seconds before re-fetching to optimize user battery life and network bandwidth.
Live Interactive API Sandbox
Test the live endpoint directly in your browser. Choose your query filters and execute a real-time HTTP GET request.
Category
All Categories
DIY Recipes (diys)
Materials & NMTs (materials)
2.0 Furniture (furniture)
Max Bells (maxbells)
Villagers in Boxes (villagers)
Access Type
All (Free + VIP)
Free Public Islands Only
VIP Passes Only
Queue Status
All Statuses
Open Slots Only (< 7)
Full (7/7)
Send Live Request
GET https://genacnh.com/api/v1/public/active-hosts
Click "Send Live Request" above to test the API in real time...
Twitch & Kick Chatbot Integration
Allow viewers in your Twitch, Kick, or YouTube stream chat to query live, automated Dodo codes with a simple !dodo or !islands command.
1. Nightbot One-Click Command
Paste this command directly into your Twitch chat (or Nightbot Dashboard):
Copy
!commands add !dodo $(urlfetch https://genacnh.com/api/v1/public/dodo?category=all)
2. StreamElements Command
Paste this command in your Twitch chat for StreamElements bot:
Copy
!command add !dodo ${customapi.https://genacnh.com/api/v1/public/dodo?category=all}
Category-Specific Filter Variations
DIY Recipes Only : https://genacnh.com/api/v1/public/dodo?category=diys
Materials & Golden Nuggets : https://genacnh.com/api/v1/public/dodo?category=materials
Max Bells (999M) : https://genacnh.com/api/v1/public/dodo?category=maxbells
2.0 Furniture Sets : https://genacnh.com/api/v1/public/dodo?category=furniture
OBS / Streamlabs Live Broadcast Overlay
Add a live, transparent glassmorphic Dodo code HUD directly onto your OBS / Streamlabs stream layout. It automatically polls the server every 10 seconds and animates when a Dodo code changes.
OBS Browser Source Settings:
URL : https://genacnh.com/widget/stream.php?category=all
Width : 400
Height : 220
Custom CSS : Leave default (background is already transparent)
Preview Live Overlay Widget
Discord.js (v14) Slash Command Integration
Ready-to-use /islands Discord slash command with interactive embeds and direct join action buttons:
Copy
const { SlashCommandBuilder, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
module.exports = {
data: new SlashCommandBuilder()
.setName('islands')
.setDescription('View live open Animal Crossing treasure islands & Dodo codes')
.addStringOption(option =>
option.setName('category')
.setDescription('Filter island by item category')
.addChoices(
{ name: 'All Categories', value: 'all' },
{ name: 'DIY Recipes', value: 'diys' },
{ name: 'Materials & Gold', value: 'materials' },
{ name: 'Max Bells', value: 'maxbells' },
{ name: 'Furniture Sets', value: 'furniture' },
{ name: 'Villagers in Boxes', value: 'villagers' }
)
),
async execute(interaction) {
await interaction.deferReply();
const category = interaction.options.getString('category') || 'all';
try {
const res = await fetch(`https://genacnh.com/api/v1/public/active-hosts?category=${category}&type=free&limit=5`);
const data = await res.json();
if (!data.success || !data.hosts || data.hosts.length === 0) {
return interaction.editReply('ποΈ **All treasure islands are currently full or restarting.** Check live queue: https://genacnh.com/islands.php');
}
const embed = new EmbedBuilder()
.setTitle('ποΈ GenACNH Live Public Treasure Islands')
.setDescription(`Found **${data.total_active_hosts}** online public islands. Fly via Dodo Code at your airport!`)
.setColor(0x2dd4bf)
.setThumbnail('https://genacnh.com/images/logo/GenACNH_Logo.png')
.setTimestamp()
.setFooter({ text: 'Powered by GenACNH Island Automation Network', iconURL: 'https://genacnh.com/images/logo/GenACNH_Logo.png' });
data.hosts.forEach(isl => {
const statusDot = (isl.available_slots > 0) ? 'π’ OPEN' : 'π΄ FULL';
embed.addFields({
name: `${isl.name} Β· ${isl.category_label}`,
value: `π **Dodo Code:** \`${isl.dodo_code}\`\nπ₯ **Visitors:** ${isl.current_visitors}/${isl.max_visitors} (${statusDot})\nπ *${isl.description}*`,
inline: false
});
});
const row = new ActionRowBuilder().addComponents(
new ButtonBuilder()
.setLabel('View Live Map Directory')
.setStyle(ButtonStyle.Link)
.setURL('https://genacnh.com/islands.php')
);
await interaction.editReply({ embeds: [embed], components: [row] });
} catch (err) {
console.error('GenACNH API Error:', err);
await interaction.editReply('β Failed to fetch treasure island status. Please try again in a few seconds.');
}
}
};
Discord 30s Auto-Updating Status Channel
Keep a dedicated #treasure-islands Discord channel automatically updated in real time every 30 seconds:
Copy
const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');
const client = new Client({ intents: [GatewayIntentBits.Guilds] });
const STATUS_CHANNEL_ID = "YOUR_DISCORD_CHANNEL_ID_HERE";
let statusMessageId = null;
async function updateIslandStatusChannel() {
try {
const channel = await client.channels.fetch(STATUS_CHANNEL_ID);
if (!channel) return;
const res = await fetch("https://genacnh.com/api/v1/public/active-hosts?type=free&limit=10");
const data = await res.json();
const embed = new EmbedBuilder()
.setTitle("ποΈ Live Animal Crossing Treasure Islands Directory")
.setDescription(`Real-time Dodo Codes for open automated SysBot islands.\n*Updated every 30 seconds.*`)
.setColor(0x10b981)
.setThumbnail("https://genacnh.com/images/logo/GenACNH_Logo.png")
.setTimestamp()
.setFooter({ text: "GenACNH Island Automation Network" });
if (data.hosts && data.hosts.length > 0) {
data.hosts.forEach(isl => {
embed.addFields({
name: `π ${isl.name} (${isl.category_label})`,
value: `π« **Dodo:** \`${isl.dodo_code}\` | **Queue:** ${isl.current_visitors}/${isl.max_visitors} (${isl.status})`,
inline: true
});
});
} else {
embed.addFields({ name: "Offline", value: "All islands are currently cycling. Please check back shortly!" });
}
if (!statusMessageId) {
const msg = await channel.send({ embeds: [embed] });
statusMessageId = msg.id;
} else {
const msg = await channel.messages.fetch(statusMessageId);
await msg.edit({ embeds: [embed] });
}
} catch (e) {
console.error("Status channel update error:", e);
}
}
client.once('ready', () => {
console.log(`Bot logged in as ${client.user.tag}`);
updateIslandStatusChannel();
setInterval(updateIslandStatusChannel, 30000); // Poll every 30s
});
client.login("YOUR_DISCORD_BOT_TOKEN_HERE");
Discord.py (v2.0+) Slash Command
Asynchronous slash command for Python Discord bots using aiohttp:
Copy
import discord
from discord import app_commands
from discord.ext import commands
import aiohttp
class IslandCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="islands", description="Display live ACNH treasure islands & Dodo codes")
@app_commands.describe(category="Filter by item theme (e.g. diys, materials, maxbells, all)")
async def islands(self, interaction: discord.Interaction, category: str = "all"):
await interaction.response.defer()
url = f"https://genacnh.com/api/v1/public/active-hosts?category={category}&type=free&limit=5"
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
if resp.status != 200:
return await interaction.followup.send("β Could not connect to GenACNH API.")
data = await resp.json()
hosts = data.get("hosts", [])
if not hosts:
return await interaction.followup.send("ποΈ No public islands currently open. Check https://genacnh.com/islands.php")
embed = discord.Embed(
title="ποΈ GenACNH Live Treasure Islands",
description=f"Showing **{len(hosts)}** active automated islands. Fly via Dodo Code!",
color=0x2DD4BF
)
embed.set_thumbnail(url="https://genacnh.com/images/logo/GenACNH_Logo.png")
embed.set_footer(text="Powered by GenACNH Island Automation Network", icon_url="https://genacnh.com/images/logo/GenACNH_Logo.png")
for isl in hosts:
embed.add_field(
name=f"{isl['name']} ({isl['category_label']})",
value=f"π **Dodo:** `{isl['dodo_code']}`\nπ₯ **Capacity:** {isl['current_visitors']}/{isl['max_visitors']} ({isl['status']})\nπ [View on GenACNH]({isl['web_url']})",
inline=False
)
await interaction.followup.send(embed=embed)
async def setup(bot):
await bot.add_cog(IslandCog(bot))
POST
/api/v1/island/update
Registers or updates Treasure Island status, live Dodo Code, categories, custom banner background, and pass pricing.
Request Parameters
Param Type Req Description
island_namestring Yes Island display name (e.g. Nook Haven)
dodo_codestring Yes 5-character Dodo Code (e.g. 5K9LM)
categorystring No diys | materials | nookmiles | furniture | villagers | clothes | all_items
banner_urlstring No Direct HTTPS image URL for custom background banner / thumbnail
map_urlstring No Direct HTTPS image URL for top-down Item Layout Map (enables zoom viewer & map badge)
is_onlineint No 1 = Online, 0 = Offline
is_paidint No 0 = Free, 1 = VIP Pass Required
pass_pricefloat No Single Island Pass Price in USD (configured in Portal or API)
Response (200 OK)
Copy
{
"success": true,
"message": "Treasure Island updated successfully",
"island_id": 14,
"dodo_code": "5K9LM",
"map_url": "https://i.imgur.com/your-item-map.png",
"is_online": true
}
Custom Banner & Item Layout Map Guide
Hosters can brand their Treasure Island with a custom photo banner and provide a high-resolution Item Layout Map . When configured, your island displays a πΊοΈ MAP badge in the directory, a Quick Map preview modal, and an interactive zoomable layout guide on the boarding page.
How to Configure Layout Maps
In Developer Portal : Click the Add/Edit Map button next to any of your listed islands.
In SysBot (config.json) : Set "MapUrl": "https://i.imgur.com/your-item-map.png" inside TreasureIslandConfig.
Via REST API : Pass map_url in your POST /api/v1/island/update payload.
Recommended Specifications
Asset Type Aspect Ratio Recommended Resolution Formats
Island Banner 16:91200 x 675 pxJPG, PNG, WEBP
Item Layout Map 1:1 or 4:31080 x 1080 px to 2048 x 2048 pxPNG, JPG, WEBP
POST
/api/v1/island/heartbeat
Periodic keep-alive ping (call every 30β60s) to retain online status.
Request Parameters
Param Type Req Description
island_idint Yes ID of the Treasure Island
Response (200 OK)
Copy
{
"success": true,
"status": "online"
}
POST
/api/v1/island/visitor
Tracks visitor arrivals and departures for real-time capacity monitoring.
Request Parameters
Param Type Req Description
island_idint Yes ID of the Treasure Island
actionstring Yes arrival or departure
Response (200 OK)
Copy
{
"success": true,
"action": "arrival",
"current_visitors": 4
}
GET
/api/v1/island/subscribers
Validates resident VIP pass or bundle pass authorization.
Query Parameters
Param Type Req Description
island_idint Yes Target Treasure Island ID
user_idint Yes Resident User ID
Response (200 OK)
Copy
{
"success": true,
"is_subscribed": true,
"bundle_type": "custom_bundle",
"expires_at": "2026-09-15 23:59:59"
}
POST
/api/developer/bundles/create
Creates a custom multi-island bundle pass across bot applications.
JSON Payload
Param Type Req Description
bundle_namestring Yes Bundle title (e.g. Diy & Villager Pass)
bundle_pricefloat Yes Monthly price in USD (e.g. 7.99)
included_island_idsstring Yes Comma-separated island IDs (e.g. "1,4")
Response (200 OK)
Copy
{
"success": true,
"message": "Custom Multi-Island Bundle created successfully",
"bundle_id": 8
}
POST
/api/developer/bundles/delete
Deletes an existing custom multi-island bundle pass.
Request Parameters
Param Type Req Description
bundle_idint Yes ID of the bundle to delete
Response (200 OK)
Copy
{
"success": true,
"message": "Custom bundle deleted successfully"
}
Swift (iOS Companion Apps β ACNH Guide)
Fetch and decode live active treasure islands in Swift for native iOS and iPadOS companion applications:
Copy
import Foundation
struct GenACNHResponse: Codable {
let success: Bool
let totalActiveHosts: Int
let freePublicHosts: Int
let hosts: [IslandHost]
enum CodingKeys: String, CodingKey {
case success
case totalActiveHosts = "total_active_hosts"
case freePublicHosts = "free_public_hosts"
case hosts
}
}
struct IslandHost: Codable, Identifiable {
let id: Int
let name: String
let category: String
let categoryLabel: String
let description: String
let dodoCode: String
let isFree: Bool
let status: String
let currentVisitors: Int
let maxVisitors: Int
let availableSlots: Int
let webUrl: String
enum CodingKeys: String, CodingKey {
case id, name, category, description, status
case categoryLabel = "category_label"
case dodoCode = "dodo_code"
case isFree = "is_free"
case currentVisitors = "current_visitors"
case maxVisitors = "max_visitors"
case availableSlots = "available_slots"
case webUrl = "web_url"
}
}
func fetchActiveTreasureIslands(completion: @escaping ([IslandHost]?) -> Void) {
guard let url = URL(string: "https://genacnh.com/api/v1/public/active-hosts?type=free&status=open") else { return }
URLSession.shared.dataTask(with: url) { data, _, error in
guard let data = data, error == nil else {
completion(nil)
return
}
let response = try? JSONDecoder().decode(GenACNHResponse.self, from: data)
DispatchQueue.main.async {
completion(response?.hosts)
}
}.resume()
}
Kotlin (Android Companion Apps)
Query live automated islands using OkHttp or Coroutines in Android applications:
Copy
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import org.json.JSONObject
class GenACNHRepository {
private val client = OkHttpClient()
suspend fun getActiveTreasureIslands(category: String = "all"): String = withContext(Dispatchers.IO) {
val request = Request.Builder()
.url("https://genacnh.com/api/v1/public/active-hosts?category=$category&type=free")
.header("User-Agent", "ACNHCompanionApp/1.0")
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) throw Exception("HTTP ${response.code}")
response.body?.string() ?: ""
}
}
}
JavaScript / TypeScript (Fetch API & Web Apps)
Copy
// Fetch open public treasure islands from GenACNH
async function getLiveTreasureIslands(category = 'all') {
try {
const response = await fetch(`https://genacnh.com/api/v1/public/active-hosts?category=${category}&type=free&status=open`);
const data = await response.json();
if (data.success) {
console.log(`Found ${data.total_active_hosts} online islands:`, data.hosts);
return data.hosts;
}
} catch (err) {
console.error("Failed to load GenACNH active hosts:", err);
}
return [];
}
C# (SysBot.ACNHOrders)
Copy
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
public class GenACNHHostClient
{
private static readonly HttpClient client = new HttpClient();
private const string BotToken = "YOUR_BOT_TOKEN_HERE";
public static async Task UpdateIslandStatusAsync(string islandName, string dodoCode, string category = "all_items", string bannerUrl = "")
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("X-Bot-Token", BotToken);
client.DefaultRequestHeaders.UserAgent.ParseAdd("SysBot.GenACNH/1.0");
var values = new Dictionary
{
{ "island_name", islandName },
{ "dodo_code", dodoCode },
{ "category", category },
{ "banner_url", bannerUrl },
{ "is_online", "1" },
{ "is_paid", "0" },
{ "max_visitors", "7" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://genacnh.com/api/v1/island/update", content);
string result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"[GenACNH API] {result}");
}
}
Python
Copy
import requests
headers = {
"X-Bot-Token": "YOUR_BOT_TOKEN_HERE",
"User-Agent": "SysBot.GenACNH/1.0"
}
payload = {
"island_name": "Starry Beach",
"dodo_code": "8M2KP",
"category": "diys",
"banner_url": "https://i.imgur.com/example-banner.jpg",
"is_online": 1,
"max_visitors": 7
}
res = requests.post("https://genacnh.com/api/v1/island/update", headers=headers, data=payload)
print(res.json())
cURL Reference
Copy
curl -X POST "https://genacnh.com/api/v1/island/update" \
-H "X-Bot-Token: YOUR_BOT_TOKEN_HERE" \
-H "User-Agent: SysBot.GenACNH/1.0" \
-F "island_name=Nook Haven" \
-F "dodo_code=5K9LM" \
-F "category=all_items" \
-F "banner_url=https://i.imgur.com/example-banner.jpg" \
-F "is_online=1"