<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AbdulmalikAlayande</title>
    <description>The latest articles on DEV Community by AbdulmalikAlayande (@abdulmalikalayande).</description>
    <link>https://dev.to/abdulmalikalayande</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1190284%2Fee98b5f2-954a-4394-999c-abdc303ecaa2.jpeg</url>
      <title>DEV Community: AbdulmalikAlayande</title>
      <link>https://dev.to/abdulmalikalayande</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdulmalikalayande"/>
    <language>en</language>
    <item>
      <title>OAUTH2.0 In Action — A Guide To Implementing OAUTH In Apps and Websites.</title>
      <dc:creator>AbdulmalikAlayande</dc:creator>
      <pubDate>Fri, 03 Jul 2026 12:44:56 +0000</pubDate>
      <link>https://dev.to/abdulmalikalayande/oauth20-in-action-a-guide-to-implementing-oauth-in-apps-and-websites-31h8</link>
      <guid>https://dev.to/abdulmalikalayande/oauth20-in-action-a-guide-to-implementing-oauth-in-apps-and-websites-31h8</guid>
      <description>&lt;h3&gt;
  
  
  Table of contents
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What is OAUTH&lt;/li&gt;
&lt;li&gt;&lt;a href="//#a-trip-to-oauth1.0-ville"&gt;A trip to OAUTH1.0Ville&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//#what-is-oauth2.0"&gt;What is OAUTH2.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Examples of OAUTH Technology&lt;/li&gt;
&lt;li&gt;OIDC&lt;/li&gt;
&lt;li&gt;Hands-on Implementation with Microsoft Entra ID&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is OAUTH
&lt;/h2&gt;

&lt;p&gt;OAUTH is a technological standard that allows you to authorize one app or service to sign in to another without divulging private information, such as passwords.&lt;/p&gt;

&lt;p&gt;OAUTH stands for &lt;strong&gt;Open-Authorization&lt;/strong&gt;, not &lt;strong&gt;Authentication&lt;/strong&gt;. Authentication is a process that verifies your identity, although OAUTH involves identity verification, its main purpose is to grant access to connect you with different apps and services without requiring you to create a new account.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does OAUTH Work
&lt;/h2&gt;

&lt;p&gt;OAUTH uses access tokens, and this is what makes OAUTH secure to use. An access token is a piece of data that contains information about the user and the resource the token is intended for. &lt;strong&gt;A token will also include specific rules for data sharing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, you want to share your photos from Instagram with &lt;a href="https://kyrierapp.com" rel="noopener noreferrer"&gt;Kyrier — An intelligent email platform built for professionals who refuse to let their inbox run their day&lt;/a&gt;, but you only want Kyrier to access your profile image. Kyrier does not also need to access your direct messages or friends list. Instagram issues an access token to Kyrier to access the data you approve (your profile image in this case) on your behalf. So an access token will only allow Kyrier to access your profile image, not even other photos on your page. There may be rules governing when Kyrier can use the access token, it might be for a single use or for recurring uses, and it always has an expiration date.&lt;/p&gt;

&lt;h2&gt;
  
  
  A trip to OAUTH1.0Ville
&lt;/h2&gt;

&lt;p&gt;Welcome to OAuth1.0Ville. Please keep your hands inside the vehicle.&lt;/p&gt;

&lt;p&gt;This is where OAuth started. It was built &lt;strong&gt;only for websites&lt;/strong&gt;, back when "an app" meant a web page and nothing else. Although it  worked, it had a lot of problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only &lt;strong&gt;three authorization flows&lt;/strong&gt; (2.0 has six)&lt;/li&gt;
&lt;li&gt;No real plan for mobile or modern apps&lt;/li&gt;
&lt;li&gt;A scaling problem it never solved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also makes you cryptographically sign &lt;strong&gt;every single request&lt;/strong&gt;, which does not sound like a problem until you are the one debugging why your signature does not match at 2am.&lt;/p&gt;

&lt;p&gt;Today almost nobody builds with OAuth1.0. OAuth2.0 is the new standard everyone uses and agrees with.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is OAUTH2.0
&lt;/h2&gt;

&lt;p&gt;OAuth 2.0 is the version you actually want. Think of it as OAuth 1.0 after it hit the gym, got a haircut, and stopped making your life difficult.&lt;/p&gt;

&lt;p&gt;It was a full redesign, not a patch. Several big tech companies threw in feedback, and the goal was simple: completely replace 1.0 and never speak of it again.&lt;/p&gt;

&lt;p&gt;Why everyone uses it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works for &lt;strong&gt;both apps and websites&lt;/strong&gt;, not just websites&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Faster and easier&lt;/strong&gt; to implement&lt;/li&gt;
&lt;li&gt;Actually &lt;strong&gt;scales&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Gives you &lt;strong&gt;six authorization flows&lt;/strong&gt; to pick from, so the handshake fits what you are building (server app, mobile app, machine-to-machine, and so on)&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You cannot upgrade OAuth 1.0 to 2.0. They are two different things. A site can technically support both, but that is like keeping a landline next to your smartphone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Examples of OAUTH Technologies
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Say you are using Zoho Cliq as a collaboration tool, and you want to know more about the people you work with, both inside and outside your organization. So you enable integration with LinkedIn, so you can learn more about people as you interact with them, without ever leaving Zoho. LinkedIn uses OAUTH to authorize Zoho, so Zoho can pull the LinkedIn profile details you allow, right inside your Zoho workspace, without you handing over your LinkedIn password.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a developer, you are most certainly familiar with GitHub, or any other Software collaboration and code hosting tools like BitBucket or GitLab. Say you are using GitHub and You wanted to link CodeRabbit with your GitHub account so it can perform automated code reviews once you push or raise a PR, You go to GitHub through the CodeRabbit website and GitHub asks you to download the app, it would then ask you to authorize a connection with the app using your GitHub identity, a process that would be handled using OAUTH. CodeRabbit can then easily access the repositories you enabled it to access and starts listening for any PR or push events, and start reviewing your codes, without you having to sign in to both services every time. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  OIDC (Open ID Connect)
&lt;/h2&gt;

&lt;p&gt;OIDC is an authentication strategy to verify a person's identity, it is similar to OAUTH in that, they both give one application access to another application's resources on behalf of the user they are requesting for. Both OIDC and OAUTH have a role to play in enabling two unrelated apps to share information without compromising user data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hands-on Implementation with Microsoft Entra ID
&lt;/h2&gt;

&lt;p&gt;Enough of theory. Let us actually create up an app that can read someone's Outlook mailbox using OAuth 2.0. We will use &lt;strong&gt;delegated&lt;/strong&gt; access, meaning the app acts on behalf of a signed-in user, not as itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All OAuth2 providers follow the &lt;strong&gt;same flow&lt;/strong&gt;: redirect the user to authorize, get a &lt;code&gt;code&lt;/code&gt; back, exchange that &lt;code&gt;code&lt;/code&gt; for tokens, fetch the user profile, then find or create the user and start a session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft killed Basic Auth for Exchange Online back in October 2022, and EWS is on life support. In 2026, the only to authorize apps to access data on a users behalf using OAuth 2.0 is through Microsoft Graph, and that is what we will do now.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 1: Register your app in Microsoft Entra ID
&lt;/h3&gt;

&lt;p&gt;Go to the Microsoft Entra admin center (portal.azure.com), go to &lt;strong&gt;Microsoft Entra ID &amp;gt; App registrations &amp;gt; New registration&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Creating a new app normally is now impossible, you have to join the Microsoft 365 Developer Program &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Give it a recognizable name (this is really important)&lt;/li&gt;
&lt;li&gt;Pick who can use it (single tenant is fine for now)&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;Redirect URI&lt;/strong&gt;. Pick &lt;strong&gt;Web&lt;/strong&gt; if it is a server-side app, or &lt;strong&gt;SPA&lt;/strong&gt; if it is a single-page app. Use something like &lt;code&gt;https://localhost/myapp/&lt;/code&gt; for local testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Click on register. On the &lt;strong&gt;Overview&lt;/strong&gt; page, copy two things you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Application (client) ID&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Directory (tenant) ID&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Get a secret (or better, a certificate)
&lt;/h3&gt;

&lt;p&gt;Go to &lt;strong&gt;Certificates &amp;amp; secrets &amp;gt; New client secret&lt;/strong&gt;. Copy the &lt;strong&gt;Value&lt;/strong&gt; immediately. It is shown exactly once, then it is gone forever and you will be making a new one. Ask me how I know 😂.&lt;/p&gt;

&lt;p&gt;Note: certificates are more secure than secrets for production. For a hands-on demo like this, a secret is fine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Add the permissions you need
&lt;/h3&gt;

&lt;p&gt;Go to &lt;strong&gt;API permissions &amp;gt; Add a permission &amp;gt; Microsoft Graph &amp;gt; Delegated permissions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For reading mail, add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;User.Read&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Mail.Read&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;offline_access&lt;/code&gt; (this is the one that gets you a refresh token, do not skip it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only ask for what you need. The whole point of OAuth is that you do not grab the entire mailbox when you only want to read it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Send the user to log in (authorization request)
&lt;/h3&gt;

&lt;p&gt;Redirect the user to the authorize endpoint. This is the screen where they log in and approve your permissions:&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>microsoft</category>
      <category>security</category>
      <category>oidc</category>
    </item>
    <item>
      <title>Nigerian Government Fees API: AI-Powered Public Service Data</title>
      <dc:creator>AbdulmalikAlayande</dc:creator>
      <pubDate>Mon, 15 Dec 2025 07:57:22 +0000</pubDate>
      <link>https://dev.to/abdulmalikalayande/nigerian-government-fees-api-ai-powered-public-service-data-3321</link>
      <guid>https://dev.to/abdulmalikalayande/nigerian-government-fees-api-ai-powered-public-service-data-3321</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/xanochallenge"&gt;Xano AI-Powered Backend Challenge&lt;/a&gt;: Production-Ready Public API&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built the Nigerian Government and Public Utility Fees API, a production-ready REST API that provides verified, structured, and traceable information about Nigerian government fees and public utility costs and centralizes the information from multiple Nigerian agencies into one accessible endpoint.&lt;/p&gt;

&lt;p&gt;In Nigeria, citizens often struggle to find accurate information about the official cost of services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;National Identification Number (NIN) services&lt;/li&gt;
&lt;li&gt;WAEC / NECO / JAMB examination fees&lt;/li&gt;
&lt;li&gt;Passport and identity-related processes&lt;/li&gt;
&lt;li&gt;Electricity tariffs across different DisCos&lt;/li&gt;
&lt;li&gt;Other government-regulated public fees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For most Nigerians, finding accurate government fee information is frustrating. Information is usually scattered across PDFs, outdated websites, or unofficial sources. This API centralizes that data into a clean, developer-friendly backend that can be reliably consumed by applications, chatbots, dashboards, and AI agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A single API that provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;90+ verified government fees across 6 categories (Identity, Immigration, Education, Electricity, Transport, Business)&lt;/li&gt;
&lt;li&gt;6 official agencies: NIMC, NIS, NECO, JAMB, NERC, UNILAG&lt;/li&gt;
&lt;li&gt;Complete documentation with code examples in JavaScript, Python, and cURL&lt;/li&gt;
&lt;li&gt;Rich relationship data: Every fee includes category, agency, and official source information&lt;/li&gt;
&lt;li&gt;Search &amp;amp; filtering: Find exactly what you need instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API is built with a strong focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;official data sources&lt;/li&gt;
&lt;li&gt;traceability&lt;/li&gt;
&lt;li&gt;maintainability&lt;/li&gt;
&lt;li&gt;real-world production usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Live API URL&lt;/strong&gt;: &lt;code&gt;https://xmlb-8xh6-ww1h.n7e.xano.io/api:public&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  API Documentation
&lt;/h2&gt;

&lt;p&gt;The API follows a simple and predictable REST structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Categories (e.g. Identity &amp;amp; Management, Education, Electricity)&lt;/li&gt;
&lt;li&gt;Subcategories (e.g. NIN, NECO, JAMB, Passport, DisCos)&lt;/li&gt;
&lt;li&gt;Fees (individual payable items)&lt;/li&gt;
&lt;li&gt;Agencies (government bodies)&lt;/li&gt;
&lt;li&gt;Sources (official documents and websites)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Base URL&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://xmlb-8xh6-ww1h.n7e.xano.io/api:public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;API key via query parameter: &lt;code&gt;?api_key=YOUR_KEY&lt;/code&gt;&lt;br&gt;
Test API Key: &lt;code&gt;nga_b6cf98a60bda43ba8cf54af9dbd87260&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Available Endpoints&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  1. POST /api_key/generate
&lt;/h4&gt;

&lt;p&gt;Generates the API key to be used for accessing the secured endpoints.&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; &lt;span class="s1"&gt;'POST''https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/api_key/generate'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"user_email":"your-email@example.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2.  GET /fees
&lt;/h4&gt;

&lt;p&gt;Retrieve paginated list of fees with optional filtering.&lt;br&gt;
Parameters:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;category&lt;/code&gt; (optional) - Filter by category name/slug&lt;br&gt;
&lt;code&gt;state&lt;/code&gt; (optional) - Filter by state&lt;br&gt;
&lt;code&gt;search&lt;/code&gt; (optional) - Search in name and description&lt;br&gt;
&lt;code&gt;page&lt;/code&gt; (optional, default: 1) - Page number&lt;br&gt;
&lt;code&gt;per_page&lt;/code&gt; (optional, default: 20, max: 100) - Results per page&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees?category=identity&amp;amp;per_page=5'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. GET /fees/{id}
&lt;/h4&gt;

&lt;p&gt;Get single fee by ID with all relationships.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees/1?api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. GET /fees/search
&lt;/h4&gt;

&lt;p&gt;Search fees by name and description (min 2 characters).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees/search?q=passport&amp;amp;api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. GET /categories
&lt;/h4&gt;

&lt;p&gt;Get all categories with fee counts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/categories?api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. GET /metadata
&lt;/h4&gt;

&lt;p&gt;Get API statistics and version information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/metadata?api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rate Limits
&lt;/h3&gt;

&lt;p&gt;Currently no rate limits enforced. Request tracking is implemented for future rate limiting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Response Format
&lt;/h3&gt;

&lt;p&gt;All responses are JSON. Errors follow standardized format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR_CODE_TYPE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Human-readable error message"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full documentation:&lt;/strong&gt; Available in my GitHub repository with complete request/response examples, error handling, and integration guides.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Example 1: Generate API Key
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; &lt;span class="s1"&gt;'POST''https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/api_key/generate'&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"user_email":"your-email@example.com"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"api_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"nga_********************************"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"API key generated successfully. Please save this key as it provides access to the API."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2: Get All Categories
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; &lt;span class="s1"&gt;'GET'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/categories?api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identity &amp;amp; Management"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fees related to national identity systems such as NIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fee_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Immigration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Passport and visa related fees"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fee_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Education"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NECO, JAMB and related examination fees"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fee_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 3: Search for NIN Fees
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; &lt;span class="s1"&gt;'GET'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees/search?q=NIN&amp;amp;api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NIN Enrolment (First Time)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NGN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"service_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Standard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Initial NIN enrollment is free"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Identity &amp;amp; Management"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agency_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"National Identity Management Commission"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"subcategory_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NIN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NIMC"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 4: Get Fee Details
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Request:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; &lt;span class="s1"&gt;'GET'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees/20?api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'accept: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Standard Passport 32 Pages (5-Year Validity)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NGN"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"service_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Standard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"New or Renewal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subcategory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Passport"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Immigration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Passport and visa related fees"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nigerian Immigration Service (NIS)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agency"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nigeria Immigration Service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://immigration.gov.ng"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code Integration Examples
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;JavaScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://xmlb-8xh6-ww1h.n7e.xano.io/api:public&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nga_b6cf98a60bda43ba8cf54af9dbd87260&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;searchFees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BASE_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/fees/search?q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;api_key=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Found &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; fees matching "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;searchFees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;passport&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://xmlb-8xh6-ww1h.n7e.xano.io/api:public&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;nga_b6cf98a60bda43ba8cf54af9dbd87260&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_fees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/fees/search&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;api_key&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Found &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; fees matching &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;

&lt;span class="nf"&gt;search_fees&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;passport&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Try it yourself with your API key, see the example provided above!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The AI Prompt I Used
&lt;/h2&gt;

&lt;p&gt;I used &lt;strong&gt;Cursor with XanoScript&lt;/strong&gt; to generate all 5 core endpoints. Here's my main prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate 5 Xano API endpoints for a Nigerian government fees API:

1. GET /fees
   - Query fees table with optional filters: category, state, search
   - Include relationships: subcategory, category, agency, source
   - Add pagination: limit (default 50), offset (default 0)
   - Return JSON with data array and metadata

2. GET /fees/{id}
   - Get single fee by ID with all relationships
   - Return 404 if not found
   - Include subcategory, category, source, and agency data

3. GET /categories
   - List all categories
   - Include count of fees in each category
   - Return with display_name and description

4. GET /fees/search
   - Accept 'q' query parameter (required, minimum 2 characters)
   - Search in fee name and description using case-insensitive match
   - Limit to 20 results
   - Include all relationships

5. GET /metadata
   - Return API statistics (total fees, categories, agencies)
   - Include last database update timestamp
   - Return API version number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AI delivered in ~30 minutes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete XanoScript code for all 5 endpoints&lt;/li&gt;
&lt;li&gt;Database query structures with joins&lt;/li&gt;
&lt;li&gt;Basic input validation&lt;/li&gt;
&lt;li&gt;Pagination logic&lt;/li&gt;
&lt;li&gt;Error handling with preconditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time saved:&lt;/strong&gt; ~6 hours of boilerplate coding&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Refined the AI-Generated Code
&lt;/h2&gt;

&lt;p&gt;AI gave me a great starting point, but I had to fix critical bugs and add production features. Here are the key refinements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue #1: Invalid &lt;code&gt;eval&lt;/code&gt; Syntax - CRITICAL BUG
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd8nc03svgozh291whp3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd8nc03svgozh291whp3t.png" alt=" " width="800" height="442"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;AI Generated (GET /fees/{id}):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;category&lt;/span&gt;   &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.{}&lt;/span&gt;
  &lt;span class="nl"&gt;subcategory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.{}&lt;/span&gt;
  &lt;span class="nl"&gt;agency&lt;/span&gt;     &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.{}&lt;/span&gt;
  &lt;span class="nl"&gt;source&lt;/span&gt;     &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; &lt;code&gt;$db.{}&lt;/code&gt; is invalid XanoScript syntax. This caused relationships to fail silently—no error in development, but incomplete data in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Removed invalid eval block&lt;/span&gt;
&lt;span class="c1"&gt;// Used db.get to fetch relationships separately&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$subcategory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subcategories&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$fee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subcategory_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$category&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;categories&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$subcategory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$source&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sources&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$fee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$agency&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;agencies&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;agency_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Then nested them properly using var.update&lt;/span&gt;
&lt;span class="nx"&gt;$fee&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nl"&gt;subcategory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;$subcategory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$category&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;$source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;agency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$agency&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Relationships now properly included in every response. API went from returning incomplete data to being production-ready.&lt;/p&gt;




&lt;h3&gt;
  
  
  Issue #2: N+1 Query Performance Problem
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AI Generated (GET /categories):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;foreach &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$categories&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;$category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Query fees for EACH category individually - terrible for performance!&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$fee_count&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fees&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;subcategory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; If you have 6 categories, this makes 6 separate database queries. Would fail under load.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Optimization:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Single query with proper aggregation&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$fee_counts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fees&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;join&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;subcategories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;categories.id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;group_by&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;categories.id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;select&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;categories.id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;fee_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COUNT(fees.id)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Reduced database queries from 6 to 1. Response time improved by ~60%.&lt;/p&gt;




&lt;h3&gt;
  
  
  Issue #3: Empty Results Bug
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; When calling &lt;code&gt;/fees&lt;/code&gt; with no filters, API returned &lt;code&gt;{"items":[],"itemsTotal":0}&lt;/code&gt; despite having 87 fees in the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause:&lt;/strong&gt; The &lt;code&gt;where&lt;/code&gt; clause was too restrictive. When optional filters were &lt;code&gt;null&lt;/code&gt;, the logical AND conditions were filtering out all records.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Added explicit null/empty checks for each optional filter&lt;/span&gt;
&lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$search_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;$search_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;$search_filter&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;$search_filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$category_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;$category_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;$category_filter&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;$category_filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$state_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;$state_filter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
   &lt;span class="nx"&gt;$db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;$state_filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; API now correctly returns all fees when no filters are applied, and properly filters when they are.&lt;/p&gt;




&lt;h3&gt;
  
  
  Issue #4: Incorrect Sort Syntax
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;AI Generated:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$db.fees.updated_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; XanoScript doesn't use &lt;code&gt;$db.&lt;/code&gt; prefix in sort blocks. Caused silent sorting failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updated_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Impact:&lt;/strong&gt; Last updated fees now correctly sorted by timestamp.&lt;/p&gt;




&lt;h3&gt;
  
  
  What I Added Beyond AI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. API Key Authentication System&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;auth_api_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Extract and validate API key&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$api_key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$http_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;api_key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;$api_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERROR_CODE_ACCESS_DENIED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing API Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Query and validate&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;$key_record&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api_keys&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$api_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;is_active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; 
    &lt;span class="p"&gt;})&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;$key_record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ERROR_CODE_ACCESS_DENIED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid or inactive API Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Update usage stats&lt;/span&gt;
  &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api_keys&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$key_record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;request_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;$key_record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request_count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;last_request_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;$key_record&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Standardized Error Responses&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ERROR_CODE_ACCESS_DENIED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Invalid or inactive API Key."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Comprehensive Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full API reference with request/response examples&lt;/li&gt;
&lt;li&gt;Quick Start guide (5 minutes to first API call)&lt;/li&gt;
&lt;li&gt;Code examples in JavaScript, Python, and cURL&lt;/li&gt;
&lt;li&gt;Data sources reference with official URLs&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The Numbers: AI vs Human Contribution
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;AI&lt;/th&gt;
&lt;th&gt;Human&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30 minutes&lt;/td&gt;
&lt;td&gt;4-5 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code Generated&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~500 lines&lt;/td&gt;
&lt;td&gt;~300 lines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Critical Bugs Found&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Production Features&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Basic CRUD&lt;/td&gt;
&lt;td&gt;Auth, optimization, error handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total Development Time:&lt;/strong&gt; ~5 hours (would have been 10-12 hours without AI)&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with Xano
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What I Found Most Helpful
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Visual Database Designer&lt;/strong&gt;&lt;br&gt;
Building the relational database schema with proper foreign keys was intuitive. The visual interface made it easy to see relationships between tables (fees → subcategories → categories → agencies).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Built-in API Testing&lt;/strong&gt;&lt;br&gt;
The "Run &amp;amp; Debug" feature in the API builder was invaluable. I could test endpoints immediately without deploying or using external tools. This caught bugs early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. XanoScript Flexibility&lt;/strong&gt;&lt;br&gt;
Having both visual blocks and code gave me the best of both worlds. For simple queries, I used the visual builder. For complex logic (like the authentication function), I wrote XanoScript directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. One-Click Deployment&lt;/strong&gt;&lt;br&gt;
No server setup, no deployment configuration, no DevOps complexity. Just build and it's live. This saved hours of infrastructure work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. PostgreSQL Under the Hood&lt;/strong&gt;&lt;br&gt;
Knowing I had a real relational database with proper ACID guarantees gave me confidence. This isn't a toy database—it's production-grade.&lt;/p&gt;


&lt;h3&gt;
  
  
  Challenges I Faced
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. XanoScript Learning Curve&lt;/strong&gt;&lt;br&gt;
Coming from Java/JavaScript/Python, XanoScript syntax had quirks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;$variable&lt;/code&gt; vs &lt;code&gt;variable&lt;/code&gt; naming conventions&lt;/li&gt;
&lt;li&gt;When to use &lt;code&gt;eval&lt;/code&gt; blocks (spoiler: less than I thought)&lt;/li&gt;
&lt;li&gt;Sort/filter syntax differences from standard SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Trial and error, plus reading Xano docs. The AI-generated code gave me examples to learn from, even when it had bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Debugging AI-Generated Code&lt;/strong&gt;&lt;br&gt;
AI confidently generated invalid syntax (&lt;code&gt;$db.{}&lt;/code&gt;) that looked plausible. Without testing, I would have shipped broken code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson Learned:&lt;/strong&gt; Always test AI-generated code immediately. AI is great at structure but can miss framework-specific nuances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Documentation Gaps&lt;/strong&gt;&lt;br&gt;
Some XanoScript features weren't well-documented online. I had to experiment to figure out the correct syntax for complex joins and aggregations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Used the Xano community forums and tested different approaches until I found what worked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. N+1 Query Gotcha&lt;/strong&gt;&lt;br&gt;
It was easy to accidentally create performance problems with nested loops. The visual builder doesn't warn you about N+1 queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Always think about database query patterns. Single complex query &amp;gt; multiple simple queries.&lt;/p&gt;


&lt;h3&gt;
  
  
  What Made This Project Successful
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Winning Combination:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Xano&lt;/strong&gt; handled infrastructure and deployment&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;AI&lt;/strong&gt; generated boilerplate and structure quickly&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Human expertise&lt;/strong&gt; fixed bugs, optimized performance, added production features&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Real data&lt;/strong&gt; from official government sources made it valuable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;None of these alone would have worked.&lt;/strong&gt; But together? I built a production-ready API in ~5 hours that would have taken 2-3 days manually.&lt;/p&gt;


&lt;h3&gt;
  
  
  Would I Use Xano Again?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Absolutely.&lt;/strong&gt; For rapid API development, especially for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hackathons&lt;/strong&gt; - Speed to deployment is unbeatable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MVPs&lt;/strong&gt; - Get to market fast, validate ideas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internal tools&lt;/strong&gt; - Build CRUD APIs in hours, not days&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prototypes&lt;/strong&gt; - Prove concepts before investing in custom infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When I might not use it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extremely high-scale applications requiring custom infrastructure&lt;/li&gt;
&lt;li&gt;Projects needing specific database features outside PostgreSQL&lt;/li&gt;
&lt;li&gt;Complex real-time features requiring WebSockets at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for 90% of backend API projects? &lt;strong&gt;Xano + AI is a game-changer.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Impact &amp;amp; Future Plans
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Who Can Use This API?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;🏦 Fintech Companies:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Budget calculators including government fees&lt;/li&gt;
&lt;li&gt;Payment platforms for government services&lt;/li&gt;
&lt;li&gt;Financial planning apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📱 Mobile Apps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Citizen services super-apps&lt;/li&gt;
&lt;li&gt;Student planning tools&lt;/li&gt;
&lt;li&gt;Government service aggregators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🤖 Chatbots:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WhatsApp bots for fee inquiries&lt;/li&gt;
&lt;li&gt;USSD services for feature phones&lt;/li&gt;
&lt;li&gt;AI government assistants&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What's Next
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Immediate (v1.1):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement rate limiting (100 req/hour)&lt;/li&gt;
&lt;li&gt;Add webhook support for fee updates&lt;/li&gt;
&lt;li&gt;Create admin dashboard for data management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Future (v2.0):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expand to all 36 Nigerian states&lt;/li&gt;
&lt;li&gt;Historical fee tracking (price changes)&lt;/li&gt;
&lt;li&gt;Multi-language support&lt;/li&gt;
&lt;li&gt;Mobile SDK&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term Vision:&lt;/strong&gt;&lt;br&gt;
Transform into a comprehensive government services platform with payment processing, application tracking, and document verification.&lt;/p&gt;


&lt;h2&gt;
  
  
  Data Sources
&lt;/h2&gt;

&lt;p&gt;All fees sourced from official government documents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NIMC:&lt;/strong&gt; SERVICE_LEVEL_AGREEMENT_2025_.pdf&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NIS:&lt;/strong&gt; Official Immigration Service SLA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NECO:&lt;/strong&gt; Official exam fees from neco.gov.ng&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JAMB:&lt;/strong&gt; Payment services from jamb.gov.ng&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NERC/EKEDC:&lt;/strong&gt; Official tariff plans from ekedp.com&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every fee includes &lt;code&gt;verification_url&lt;/code&gt; linking to the official source for transparency.&lt;/p&gt;


&lt;h2&gt;
  
  
  Try It Now!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Test API Key:&lt;/strong&gt; &lt;code&gt;nga_b6cf98a60bda43ba8cf54af9dbd87260&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Test:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s1"&gt;'https://xmlb-8xh6-ww1h.n7e.xano.io/api:public/fees/search?q=passport&amp;amp;api_key=nga_b6cf98a60bda43ba8cf54af9dbd87260'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Full Documentation:&lt;/strong&gt; &lt;a href="https://github.com/AbdulmalikAlayande/xano-ai-hackathon/" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt; (includes Quick Start guide, complete API reference, and code examples)&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This project proves that &lt;strong&gt;AI-assisted development works best as a partnership&lt;/strong&gt;: AI provides speed and structure, humans provide critical thinking and domain expertise.&lt;/p&gt;

&lt;p&gt;The Nigerian Government Fees API solves a real problem affecting millions. By centralizing scattered information into one well-documented API, we're removing barriers to accessing essential government services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;More importantly, this is just the beginning.&lt;/strong&gt; With a solid foundation, this can grow into a platform that truly improves how Nigerian citizens interact with public services.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Questions? Want to contribute? Drop a comment below! 🚀&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>xanochallenge</category>
      <category>api</category>
      <category>backend</category>
    </item>
  </channel>
</rss>
