API Reference · Public v1

Gogenx Business API

Manage your businesses from your own software: create and update them, keep their blog posts, logo and photos current, and deactivate them when you need to.

Getting started

Introduction

The Business API does from your own software what you do in the Gogenx dashboard: add businesses and send them for review, keep their details, blog posts, logo and photos up to date, and take them out of view. Every request and response is application/json.

Base URLhttps://gogenx.ai/api/public/v1
Application/JSON

A few things hold everywhere:

  • It follows the same rules as the dashboard. A new business is reviewed by our team before it goes live, starts on the Free plan, and keeps its plan’s limits. Plans are chosen and paid for in the dashboard.
  • What you read, you can send back. Field names are the same going in and coming out, so a business read with Get Business can be changed and sent to Update Business as it is.
  • Only your own account. A key reaches the businesses of the account that made it, and nothing else. Anything else answers “not found”.
  • Unknown fields are refused, not ignored, so a misspelt field name is an error you see rather than a change that silently did not happen.

Getting started

Authentication

Send your API key as a bearer token in the Authorization header of every request.

Curl
curl "https://gogenx.ai/api/public/v1/businesses" \
  -H "Authorization: Bearer gxk_your_api_key"
  • Getting a key. Sign in to Gogenx, open API & Keys and press Generate API key. It is shown once — copy it then.
  • One key per account. Rotate API key gives you a new one and stops the old one at once, so update your software straight after.
  • Keep it on your server. Anyone holding the key can change your businesses. Never put it in a web page, an app people download, or a URL.

A missing, wrong or rotated key answers 401 UNAUTHENTICATED.

Getting started

Limits

Every account has the same allowance: 10,000 requests a month, and 120 requests a minute per key.

  • The month is the calendar month in UTC; the count starts again on the 1st. Every call counts, including one refused for a mistake. Categories does not count.
  • Every response says where you are, in X-Api-Quota-Limit, X-Api-Quota-Remaining and X-Api-Quota-Reset (when the count starts again).
  • Past the allowance calls answer 429 API_QUOTA_EXCEEDED until the reset. Over the per-minute limit they answer 429 RATE_LIMITED — wait a moment and retry.
  • Businesses keep the dashboard’s limits: one logo (up to 2 MB) and 10 photos (up to 8 MB each) per business, post covers up to 5 MB, and 5 FAQs on a Free business or 25 on Pro and Scale.

Over the monthly allowance · 429 Too Many Requests

JSON
{
  "error": {
    "code": "API_QUOTA_EXCEEDED",
    "message": "This account has used all 10,000 API requests for this month. The allowance resets on 2026-10-01.",
    "requestId": "req_8f14e45f-ceea-467a-9575-5a3c1c2f3a1b",
    "details": []
  }
}
POST/businesses

Create Business

Adds a business and sends it for review in one call. It starts on the Free plan with the status submitted, and goes live (active) when our team approves it.

Send the fields in Business fields. These are required: businessName, primaryCategoryCode, streetAddress, city, stateRegion, postalCode (except in countries without postal codes), countryCode, publicPhone, contactFirstName, contactLastName, businessContactEmail, and a description or shortDescription.

If anything required is missing, nothing is created and the error names every missing field at once. Send an Idempotency-Key header so that retrying after a timeout cannot create the business twice — see Safe retries.

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: blue-sky-bakery-austin" \
  -d '{
  "businessName": "Blue Sky Bakery",
  "primaryCategoryCode": "bakeries",
  "additionalCategoryCodes": ["coffee-houses-and-tea-rooms"],
  "shortDescription": "Sourdough, pastries and coffee, baked fresh every morning.",
  "description": "A neighbourhood bakery in downtown Austin. Everything is baked on site from 5am, with a slow-rise sourdough, seasonal pastries and locally roasted coffee.",
  "streetAddress": "123 Main St",
  "city": "Austin",
  "stateRegion": "TX",
  "postalCode": "78701",
  "countryCode": "US",
  "latitude": 30.2672,
  "longitude": -97.7431,
  "timezone": "America/Chicago",
  "publicPhone": "+1 512 555 0142",
  "publicEmail": "hello@blueskybakery.com",
  "website": "https://blueskybakery.com",
  "contactFirstName": "Casey",
  "contactLastName": "Rivera",
  "businessContactEmail": "casey@blueskybakery.com",
  "hours": {
    "days": {
      "mon": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
      "tue": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
      "wed": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
      "thu": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
      "fri": { "closed": false, "intervals": [{ "open": "07:00", "close": "18:00" }] },
      "sat": { "closed": false, "intervals": [{ "open": "08:00", "close": "14:00" }] },
      "sun": { "closed": true, "intervals": [] }
    }
  },
  "services": [
    {
      "name": "Celebration cakes",
      "description": "Made to order, 48 hours notice.",
      "priceMinor": 4500,
      "currency": "USD"
    }
  ],
  "faqs": [
    {
      "question": "Do you bake gluten-free bread?",
      "answer": "Yes, every Friday, in a separate oven."
    }
  ],
  "languages": ["English", "Spanish"],
  "paymentMethodLabels": ["Cash", "Visa", "Apple Pay"],
  "attributes": ["Wheelchair accessible", "Outdoor seating"],
  "socialProfiles": {
    "profiles": [{ "provider": "instagram", "url": "https://instagram.com/blueskybakery" }]
  }
}'

Response · 201 Created

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "submitted",
    "plan": "free",
    "businessName": "Blue Sky Bakery",
    "submittedAt": "2026-09-17T09:30:00.000Z",
    "createdAt": "2026-09-17T09:30:41.000Z",
    "…": "every other field, as in Get Business"
  }
}

When required details are missing

Response · 400 Bad Request

JSON
{
  "error": {
    "code": "LISTING_INCOMPLETE",
    "message": "Some required details are missing, so nothing was created.",
    "requestId": "req_8f14e45f-ceea-467a-9575-5a3c1c2f3a1b",
    "details": [
      { "field": "primaryCategoryCode", "message": "Category is required." },
      { "field": "streetAddress", "message": "Street address is required." },
      { "field": "stateRegion", "message": "State or region is required." },
      { "field": "postalCode", "message": "Postal code is required." },
      { "field": "countryCode", "message": "Country is required." },
      { "field": "publicPhone", "message": "Phone number is required." },
      { "field": "contactFirstName", "message": "Contact first name is required." },
      { "field": "contactLastName", "message": "Contact last name is required." },
      { "field": "businessContactEmail", "message": "Business contact email is required." },
      { "field": "description", "message": "A description of the business is required." }
    ]
  }
}
GET/businesses

List Businesses

The businesses on your account, newest first, a page at a time. Deleted businesses are not included.

QueryTypeDescription
pageintegerWhich page. Starts at 1, which is the default.
limitintegerBusinesses per page, 1 to 100. Defaults to 20.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses?page=1&limit=20" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "businesses": [
    {
      "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
      "businessName": "Blue Sky Bakery",
      "status": "submitted",
      "plan": "free",
      "city": "Austin",
      "stateRegion": "TX",
      "countryCode": "US",
      "createdAt": "2026-09-17T09:30:41.000Z",
      "updatedAt": "2026-09-17T09:30:00.000Z"
    }
  ],
  "pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
}
GET/businesses/:id

Get Business

One business, with every field.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "submitted",
    "plan": "free",
    "businessName": "Blue Sky Bakery",
    "legalEntityName": null,
    "shortDescription": "Sourdough, pastries and coffee, baked fresh every morning.",
    "description": "A neighbourhood bakery in downtown Austin. Everything is baked on site from 5am, with a slow-rise sourdough, seasonal pastries and locally roasted coffee.",
    "primaryCategoryCode": "bakeries",
    "additionalCategoryCodes": ["coffee-houses-and-tea-rooms"],
    "industryVertical": null,
    "yearEstablished": null,
    "teamSize": null,
    "numberOfEmployees": null,
    "priceRange": null,
    "mission": null,
    "uniqueValueClaims": null,
    "publicPhone": "+1 512 555 0142",
    "mobilePhone": null,
    "publicEmail": "hello@blueskybakery.com",
    "website": "https://blueskybakery.com",
    "bookingUrl": null,
    "menuUrl": null,
    "googleMapsUrl": null,
    "contactFirstName": "Casey",
    "contactLastName": "Rivera",
    "businessContactEmail": "casey@blueskybakery.com",
    "streetAddress": "123 Main St",
    "city": "Austin",
    "stateRegion": "TX",
    "postalCode": "78701",
    "countryCode": "US",
    "latitude": 30.2672,
    "longitude": -97.7431,
    "timezone": "America/Chicago",
    "serviceArea": null,
    "hours": {
      "schemaVersion": 1,
      "days": {
        "mon": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
        "tue": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
        "wed": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
        "thu": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
        "fri": { "closed": false, "intervals": [{ "open": "07:00", "close": "18:00" }] },
        "sat": { "closed": false, "intervals": [{ "open": "08:00", "close": "14:00" }] },
        "sun": { "closed": true, "intervals": [] }
      }
    },
    "attributes": ["Wheelchair accessible", "Outdoor seating"],
    "languages": ["English", "Spanish"],
    "paymentMethodLabels": ["Cash", "Visa", "Apple Pay"],
    "socialProfiles": {
      "profiles": [{ "url": "https://instagram.com/blueskybakery", "provider": "instagram" }],
      "schemaVersion": 1
    },
    "brandColors": [],
    "brandColorUsageNote": null,
    "businessSizeTarget": null,
    "targetAudienceDescription": null,
    "keywords": [],
    "services": [
      {
        "name": "Celebration cakes",
        "description": "Made to order, 48 hours notice.",
        "priceMinor": 4500,
        "currency": "USD",
        "priceNote": null
      }
    ],
    "faqs": [
      {
        "question": "Do you bake gluten-free bread?",
        "answer": "Yes, every Friday, in a separate oven."
      }
    ],
    "submittedAt": "2026-09-17T09:30:00.000Z",
    "activatedAt": null,
    "createdAt": "2026-09-17T09:30:41.000Z",
    "updatedAt": "2026-09-17T09:30:00.000Z"
  }
}

A field with nothing in it is null or an empty list, never a placeholder.

PATCH/businesses/:id

Update Business

Changes the fields you send; everything you leave out stays as it is. PUT works the same way.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
  • Sending null clears a field that can be empty. Required fields cannot be cleared.
  • Lists are replaced whole. Sending faqs, services or keywords replaces the list with the one you send.
  • A business read with Get Business can be sent back as it is. Its id, status and plan are accepted unchanged but cannot be changed here, and its timestamps are ignored.
  • A live business stays live while it is edited. Its new details are read by our automatic content check.

Example request

Curl
curl -X PATCH "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "publicPhone": "+1 512 555 0199", "website": "https://www.blueskybakery.com" }'

Response · 200 OK

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "submitted",
    "businessName": "Blue Sky Bakery",
    "publicPhone": "+1 512 555 0199",
    "website": "https://www.blueskybakery.com",
    "updatedAt": "2026-09-17T09:32:44.000Z",
    "…": "every other field, as in Get Business"
  }
}
POST/businesses/:id/submit

Submit for Review

Sends a business for review: a draft started in the dashboard, or one our team sent back (rejected) once you have fixed it. Businesses made with Create Business are sent automatically.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/submit" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "submitted",
    "businessName": "Blue Sky Bakery East",
    "submittedAt": "2026-09-17T09:33:25.000Z",
    "…": "every other field, as in Get Business"
  }
}
DELETE/businesses/:id

Deactivate Business

Takes a live business out of public view. Its data is kept, its status becomes paused, and you can switch it back on with Reactivate Business or in the dashboard.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.

Deactivating does not cancel a paid plan. When the business is on Pro or Scale, the response includes a notice saying so; cancel the plan in the dashboard if you no longer need it.

Example request

Curl
curl -X DELETE "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "paused",
    "plan": "free",
    "businessName": "Blue Sky Bakery",
    "…": "every other field, as in Get Business"
  },
  "notice": "The Pro plan on this business is still active and billed. Cancel it in the Gogenx dashboard if it is no longer needed."
}
POST/businesses/:id/reactivate

Reactivate Business

Switches a business you deactivated back on. It goes live again straight away.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.

A business paused by our review team cannot be switched back on here; it answers 409 LISTING_PAUSED_BY_REVIEW.

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/reactivate" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "business": {
    "id": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "status": "active",
    "businessName": "Blue Sky Bakery",
    "…": "every other field, as in Get Business"
  }
}
POST/businesses/:id/posts

Create Post

Writes a blog post for a business: a draft, a post scheduled for later, or one that goes live now.

FieldTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
titleRequiredstringUp to 200 characters.
contentHtmlRequiredstringThe post, in HTML. Paragraphs, headings, lists, links, bold and italic are kept; scripts, styles and anything else are removed.
publishbooleanPut the post live now. Otherwise it is saved as a draft.
scheduledForstringAn ISO-8601 time in the future. The post goes live by itself then. Not together with publish.
coverMediaAssetIdstringThe id of a post_cover image uploaded to this business with Upload Image.

A post goes live at once and is then read by our automatic content check. Send an Idempotency-Key header to make retries safe.

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Why our sourdough rises for 18 hours",
  "contentHtml": "<p>Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour.</p><h2>Come by early</h2><p>The first loaves come out of the oven at 7am.</p>",
  "publish": true
}'

Response · 201 Created

JSON
{
  "post": {
    "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
    "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "title": "Why our sourdough rises for 18 hours",
    "slug": "why-our-sourdough-rises-for-18-hours",
    "excerpt": "Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour. Come by early The first loaves come out of the oven at 7am.",
    "status": "published",
    "source": "manual",
    "publishTiming": "auto",
    "scheduledFor": null,
    "publishedAt": "2026-09-17T09:31:22.000Z",
    "coverMediaAssetId": null,
    "hasPendingVersion": false,
    "updatedAt": "2026-09-17T09:31:22.000Z",
    "contentHtml": "<p>Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour.</p><h2>Come by early</h2><p>The first loaves come out of the oven at 7am.</p>"
  }
}
GET/businesses/:id/posts

List Posts

The business’s posts, newest first — the latest 100. The list leaves out each post’s contentHtml; Get Post includes it.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
StatusTypeDescription
draftstatusSaved, not public.
scheduledstatusGoes live by itself at scheduledFor.
publishedstatusLive on the business’s public profile.
heldstatusTaken down by the content check while our team looks at it.
generating, reviewstatusAn AI-written post still being prepared in the dashboard.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "posts": [
    {
      "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
      "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
      "title": "Why our sourdough rises for 18 hours",
      "slug": "why-our-sourdough-rises-for-18-hours",
      "excerpt": "Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour. Come by early The first loaves come out of the oven at 7am.",
      "status": "published",
      "source": "manual",
      "publishTiming": "auto",
      "scheduledFor": null,
      "publishedAt": "2026-09-17T09:31:22.000Z",
      "coverMediaAssetId": null,
      "hasPendingVersion": false,
      "updatedAt": "2026-09-17T09:31:22.000Z"
    }
  ]
}
GET/businesses/:id/posts/:postId

Get Post

One post, including its contentHtml.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
postIdRequiredpathThe post id, from Create Post or List Posts.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts/01a0b2c3-589b-77bf-924f-529143527ba6" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "post": {
    "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
    "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "title": "Why our sourdough rises for 18 hours",
    "slug": "why-our-sourdough-rises-for-18-hours",
    "excerpt": "Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour. Come by early The first loaves come out of the oven at 7am.",
    "status": "published",
    "source": "manual",
    "publishTiming": "auto",
    "scheduledFor": null,
    "publishedAt": "2026-09-17T09:31:22.000Z",
    "coverMediaAssetId": null,
    "hasPendingVersion": false,
    "updatedAt": "2026-09-17T09:31:22.000Z",
    "contentHtml": "<p>Every loaf rests overnight before it is baked. The long, cool rise gives the crust its crackle and the crumb its flavour.</p><h2>Come by early</h2><p>The first loaves come out of the oven at 7am.</p>"
  }
}

hasPendingVersion is true when an AI rewrite is waiting in the dashboard; the published words have not changed.

PATCH/businesses/:id/posts/:postId

Update Post

Changes the fields you send: title, contentHtml, scheduledFor or coverMediaAssetId (null removes the cover). PUT works the same way.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
postIdRequiredpathThe post id, from Create Post or List Posts.

A published post changes in place, like any blog: the new words appear on the public profile straight away and are read again by the content check. Its address (slug) does not change once it is live.

Example request

Curl
curl -X PATCH "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts/01a0b2c3-589b-77bf-924f-529143527ba6" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Why our sourdough rises for 18 hours (and why it matters)" }'

Response · 200 OK

JSON
{
  "post": {
    "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
    "title": "Why our sourdough rises for 18 hours (and why it matters)",
    "status": "published",
    "updatedAt": "2026-09-17T09:36:50.000Z",
    "…": "every other field, as in Get Post"
  }
}
POST/businesses/:id/posts/:postId/publish

Publish / Unpublish

Publish puts a draft or scheduled post live now. POST …/unpublish takes a published post down and makes it a draft again.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
postIdRequiredpathThe post id, from Create Post or List Posts.

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts/01a0b2c3-589b-77bf-924f-529143527ba6/publish" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "post": {
    "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
    "status": "published",
    "publishedAt": "2026-09-17T09:38:12.000Z",
    "…": "every other field, as in Get Post"
  }
}
POST/businesses/:id/posts/:postId/unpublish

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts/01a0b2c3-589b-77bf-924f-529143527ba6/unpublish" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "post": {
    "id": "01a0b2c3-589b-77bf-924f-529143527ba6",
    "status": "draft",
    "publishedAt": null,
    "…": "every other field, as in Get Post"
  }
}
DELETE/businesses/:id/posts/:postId

Delete Post

Deletes a post, and takes it off the public profile if it was live. This cannot be undone.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
postIdRequiredpathThe post id, from Create Post or List Posts.

Example request

Curl
curl -X DELETE "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/posts/01a0b2c3-589b-77bf-924f-529143527ba6" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 204 No Content

No body.

POST/businesses/:id/images

Upload Image

Adds a logo, a photo or a post cover. The file itself goes straight to our storage, so uploading takes three steps.

  1. Ask for an upload. POST /businesses/:id/images answers with the new image and an upload address.
  2. Send the file with PUT to upload.url, exactly as given, with the same Content-Type. The address works for 10 minutes. This step needs no API key and does not count as a request.
  3. Finish. POST /businesses/:id/images/:imageId/complete. We read the file back: a real PNG, JPG or WEBP within the size limit goes live, and anything else is refused and deleted.
FieldTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
typeRequiredstringlogo (one per business, up to 2 MB), photo (up to 10, 8 MB each) or post_cover (up to 5 MB).
contentTypeRequiredstringimage/png, image/jpeg or image/webp.
filenamestringThe file’s name, for your own reference.
altTextstringA short description of the picture, for people who cannot see it. Up to 300 characters.
displayOrderintegerWhere a photo sits among the others, from 0.

Step 1 · Ask for an upload

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
  "type": "photo",
  "contentType": "image/png",
  "filename": "counter.png",
  "altText": "The bread counter at opening time"
}'

Response · 201 Created

JSON
{
  "image": {
    "id": "01a0b2c3-5a21-74da-9290-e4e83a9d6257",
    "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "type": "photo",
    "status": "pending",
    "contentType": null,
    "byteSize": null,
    "filename": "counter.png",
    "altText": "The bread counter at opening time",
    "displayOrder": 0,
    "url": null,
    "urlExpiresInSeconds": null,
    "createdAt": "2026-09-17T09:32:03.000Z"
  },
  "upload": {
    "url": "https://…r2.cloudflarestorage.com/…/listing_gallery/01a0b2c3-5a21-74da-9290-e4e83a9d6257-…?X-Amz-Signature=…",
    "method": "PUT",
    "headers": { "Content-Type": "image/png" },
    "expiresInSeconds": 600,
    "maxBytes": 8388608
  }
}

Step 2 · Send the file

Curl
curl -X PUT "<upload.url from step 1>" \
  -H "Content-Type: image/png" \
  --upload-file counter.png
POST/businesses/:id/images/:imageId/complete

Step 3 · Finish

Example request

Curl
curl -X POST "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images/01a0b2c3-5a21-74da-9290-e4e83a9d6257/complete" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "image": {
    "id": "01a0b2c3-5a21-74da-9290-e4e83a9d6257",
    "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "type": "photo",
    "status": "ready",
    "contentType": "image/png",
    "byteSize": 1163,
    "filename": "counter.png",
    "altText": "The bread counter at opening time",
    "displayOrder": 0,
    "url": "https://…r2.cloudflarestorage.com/…/listing_gallery/01a0b2c3-5a21-74da-9290-e4e83a9d6257-…?X-Amz-Signature=…",
    "urlExpiresInSeconds": 300,
    "createdAt": "2026-09-17T09:32:03.000Z"
  }
}

To replace a logo, delete the old one first. A logo or photo is read by our automatic content check once it is live.

GET/businesses/:id/images

List Images

The business’s logo, photos and post covers, in display order. Each has a url to look at it, which works for 5 minutes; ask again for a fresh one.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
typequeryOnly logo, photo or post_cover.
StatusTypeDescription
pendingstatusWaiting for the file (steps 2 and 3).
readystatusLive on the business’s profile.
heldstatusHidden by the content check while our team looks at it.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images?type=photo" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "images": [
    {
      "id": "01a0b2c3-5a21-74da-9290-e4e83a9d6257",
      "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
      "type": "photo",
      "status": "ready",
      "contentType": "image/png",
      "byteSize": 1163,
      "filename": "counter.png",
      "altText": "The bread counter at opening time",
      "displayOrder": 0,
      "url": "https://…r2.cloudflarestorage.com/…/listing_gallery/01a0b2c3-5a21-74da-9290-e4e83a9d6257-…?X-Amz-Signature=…",
      "urlExpiresInSeconds": 300,
      "createdAt": "2026-09-17T09:32:03.000Z"
    }
  ]
}
GET/businesses/:id/images/:imageId

Get Image

One image, with a fresh link to look at it.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
imageIdRequiredpathThe image id, from Upload Image or List Images.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images/01a0b2c3-5a21-74da-9290-e4e83a9d6257" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 200 OK

JSON
{
  "image": {
    "id": "01a0b2c3-5a21-74da-9290-e4e83a9d6257",
    "businessId": "01a0b2c3-54d3-7d01-a6c8-566149be9778",
    "type": "photo",
    "status": "ready",
    "contentType": "image/png",
    "byteSize": 1163,
    "filename": "counter.png",
    "altText": "The bread counter at opening time",
    "displayOrder": 0,
    "url": "https://…r2.cloudflarestorage.com/…/listing_gallery/01a0b2c3-5a21-74da-9290-e4e83a9d6257-…?X-Amz-Signature=…",
    "urlExpiresInSeconds": 300,
    "createdAt": "2026-09-17T09:32:03.000Z"
  }
}
PATCH/businesses/:id/images/:imageId

Update Image

Changes an image’s altText (null clears it) or displayOrder. The picture itself cannot be changed; upload a new one instead.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
imageIdRequiredpathThe image id, from Upload Image or List Images.

Example request

Curl
curl -X PATCH "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images/01a0b2c3-5a21-74da-9290-e4e83a9d6257" \
  -H "Authorization: Bearer gxk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "altText": "Fresh loaves on the counter", "displayOrder": 1 }'

Response · 200 OK

JSON
{
  "image": {
    "id": "01a0b2c3-5a21-74da-9290-e4e83a9d6257",
    "altText": "Fresh loaves on the counter",
    "displayOrder": 1,
    "…": "every other field, as in Get Image"
  }
}
DELETE/businesses/:id/images/:imageId

Delete Image

Deletes an image and its file, and takes it off the public profile. A post using it as its cover is left without one.

ParameterTypeDescription
idRequiredpathThe business id, from Create Business or List Businesses.
imageIdRequiredpathThe image id, from Upload Image or List Images.

Example request

Curl
curl -X DELETE "https://gogenx.ai/api/public/v1/businesses/01a0b2c3-54d3-7d01-a6c8-566149be9778/images/01a0b2c3-5a21-74da-9290-e4e83a9d6257" \
  -H "Authorization: Bearer gxk_your_api_key"

Response · 204 No Content

No body.

AI assistants

Connect an assistant

Manage your businesses by chatting: connect Claude or ChatGPT to Gogenx, then ask it to update your opening hours, write a post, or check how AI platforms answer about you.

MCP serverhttps://gogenx.ai/mcp
Streamable HTTP

In Claude

On the website or in the desktop app.

  1. Open Settings → Connectors → Add custom connector and paste the address above.
  2. Sign in with Gogenx when Claude opens our sign-in page, as the owner of the account.
  3. Read the Allow screen and press Allow. It lists what the assistant can and can never do, and where you go back to.
  4. Ask it something, such as “list my businesses on Gogenx”.

In ChatGPT

Paid plans only (Plus, Pro, Business, Enterprise or Education), on the website.

  1. Turn on Developer mode in Settings → Security and login.
  2. Add an app with the address above and choose OAuth for authentication.
  3. Sign in with Gogenx and press Allow, as in Claude.

Claude and ChatGPT sign in, so each one is listed on API & Keys in the dashboard, where Remove cuts it off at once.

In Gemini

Not yet: the Gemini app does not let you add your own connector.

In Cursor

Cursor has no connector screen in its settings, so the connection goes in a file. It uses your API key instead of signing in.

  1. Create or open .cursor/mcp.json in your home folder — on Windows C:\Users\<you>\.cursor\mcp.json, on a Mac ~/.cursor/mcp.json — and put this in it, with your own key.
  2. Save the file and start Cursor again.
  3. Open the chat with Ctrl + L and ask “list my businesses using the gogenx tools”. Cursor asks permission to run the tool the first time.
JSON
{
  "mcpServers": {
    "gogenx": {
      "url": "https://gogenx.ai/mcp",
      "headers": { "Authorization": "Bearer gxk_your_api_key" }
    }
  }
}

In Claude Code

One command, run in the folder you work in. Check it with claude mcp list, which should say Connected.

Curl
claude mcp add --transport http gogenx https://gogenx.ai/mcp \
  --header "Authorization: Bearer gxk_your_api_key"

A tool that uses your API key this way is not listed under connected assistants — it is your key, so Rotate API key stops it.

For developers of assistants

Sign-in is OAuth 2.1 as the MCP authorization specification describes: protected resource metadata at /.well-known/oauth-protected-resource/mcp, authorization server metadata at /.well-known/oauth-authorization-server, PKCE with S256, and tokens bound to https://gogenx.ai/mcp with the resource parameter. Clients may register dynamically or identify themselves with a Client ID Metadata Document. Access tokens last an hour; refresh tokens are replaced each time they are used.

AI assistants

What it can do

A connected assistant acts as the owner who connected it, through the same rules as the dashboard. It asks you before it changes anything.

ToolTypeDescription
list_businessesreadYour businesses, with status, plan and city.
get_businessreadEvery detail of one business.
get_ai_visibilityreadThe latest check of how AI platforms answer about the business (Pro and Scale).
get_directory_listingsreadWhere the business is listed on the Gogenx directory network (Pro and Scale).
list_posts, get_postreadThe business’s blog posts.
list_categoriesreadFind category codes by name.
update_businesschangeChange business details, opening hours and FAQs.
create_post, update_postchangeWrite a post (saved as a draft) or edit one.
publish_postchangePut a post live.

Never available to an assistant: billing, plans or payments; deleting or deactivating a business; creating a business or sending one for review; your account, sign-in or team. Those stay in the dashboard.

Each tool call counts as one of your account’s 10,000 monthly requests. Posts and changes an assistant makes are read by the content check like any other, and your business history records them as made by an AI assistant.

Reference

Business fields

Every field of a business, as Create Business and Update Business accept it and Get Business returns it.

About the business

FieldTypeDescription
businessNameRequiredstringThe name customers know. Up to 200 characters.
legalEntityNamestringThe registered name, if different.
shortDescriptionstringOne line, up to 300 characters. A description or short description is required.
descriptionstringThe full description, up to 5,000 characters.
primaryCategoryCodeRequiredstringThe main category, a code from Categories.
additionalCategoryCodesstring[]Up to 4 more category codes.
industryVerticalstringThe wider industry, up to 80 characters.
yearEstablishedintegerFrom 1800 to this year.
teamSizestringFor example "2-10".
numberOfEmployeesintegerHow many people work there.
priceRangestring$, $$, $$$ or $$$$.
missionstringUp to 2,000 characters.
uniqueValueClaimsstringWhat sets the business apart, up to 2,000 characters.
businessSizeTargetstringThe size of customer it serves.
targetAudienceDescriptionstringWho it serves, up to 1,000 characters.

Contact

FieldTypeDescription
publicPhoneRequiredstringThe public number, for example +1 512 555 0142.
mobilePhonestringA mobile number.
publicEmailstringThe public email address.
websitestringA full address, starting https://.
bookingUrl, menuUrl, googleMapsUrlstringWhere to book, the menu, and the business on Google Maps.
contactFirstNameRequiredstringThe person we contact about this business.
contactLastNameRequiredstringTheir last name.
businessContactEmailRequiredstringWhere we contact the business.

Location

FieldTypeDescription
streetAddressRequiredstringUp to 240 characters.
cityRequiredstringUp to 120 characters.
stateRegionRequiredstringState, province or region.
postalCodeRequiredstringChecked against the country’s format. Not required in countries without postal codes.
countryCodeRequiredstringTwo-letter ISO code, for example US or GB.
latitude, longitudenumberThe map pin for the front door.
timezonestringAn IANA name, for example America/Chicago.
serviceAreastringWhere the business serves customers, up to 500 characters.

Details

FieldTypeDescription
hoursobjectOpening hours — see below.
faqsobject[]Questions an AI assistant should be able to answer about the business: { question, answer }. Up to 5 on a Free business, 25 on Pro and Scale.
servicesobject[]Up to 50: { name, description, priceMinor, currency, priceNote }. Only name is required. priceMinor is in the currency’s smallest unit — 4500 with USD is $45.00.
keywordsstring[]Up to 50 search terms.
attributesstring[]Up to 40, for example "Wheelchair accessible".
languagesstring[]Up to 20, as names ("Spanish") or codes ("es").
paymentMethodLabelsstring[]Up to 20 ways to pay.
socialProfilesobject{ profiles: [{ provider, url }] }, up to 12. provider is instagram, facebook, tiktok, x, linkedin or pinterest.
brandColorsstring[]Up to 6 hex colours, for example #ff6b35.
brandColorUsageNotestringHow the colours are used.

Set by Gogenx

FieldTypeDescription
idstringThe business’s permanent id.
statusstringdraft, submitted, under_review, active (live), rejected (sent back — fix and submit again) or paused (deactivated, or paused by our review team).
planstringfree, pro or scale. Changed in the dashboard.
submittedAt, activatedAt, createdAt, updatedAtstringISO-8601 times in UTC.

The plan, billing cycle, tax number and internal notes are only entered in the dashboard; sending them is refused with a message saying so.

Opening hours

Each day is mon to sun, with closed and up to 4 intervals for split hours, in 24-hour HH:MM. A day left out has no hours given.

JSON
{
  "hours": {
    "days": {
      "mon": { "closed": false, "intervals": [{ "open": "07:00", "close": "15:00" }] },
      "sat": {
        "closed": false,
        "intervals": [{ "open": "08:00", "close": "12:00" }, { "open": "13:00", "close": "16:00" }]
      },
      "sun": { "closed": true, "intervals": [] }
    }
  }
}
GET/categories

Categories

The category codes for primaryCategoryCode and additionalCategoryCodes. No API key is needed, and it does not count toward your requests.

Example request

Curl
curl "https://gogenx.ai/api/public/v1/categories"

Response · 200 OK

JSON
{
  "categories": [
    { "code": "bakeries", "label": "Bakeries" },
    { "code": "coffee-houses-and-tea-rooms", "label": "Coffee Houses and Tea Rooms" },
    { "code": "restaurants", "label": "Restaurants" }
  ]
}

Reference

Content check

Posts, logos, photos and post covers go live straight away, and our automatic check reads them just after. So do edits to a live business’s details.

  • A post or image the check flags is taken down at once. It reads back with "status": "held" and a notice explaining why, and our team decides whether it goes back up.
  • A held post cannot be changed or published until they finish (409 POST_HELD_FOR_REVIEW). You can still delete it.
  • If our team restores it, it goes back up exactly as it was. If they remove it, it is gone for good.
  • A flagged change to a business’s details stays live while our team looks at it; they may pause the business.

Reference

Safe retries

If a request times out, you cannot tell whether it worked. Send an Idempotency-Key header on Create Business and Create Post, and retrying is safe.

  • Use a unique value per thing you create, for example your own record’s id.
  • Sent again with the same key and body within 24 hours, the request is not repeated: you get the first answer, with the header Idempotent-Replay: true.
  • The same key with a different body is refused with 409 IDEMPOTENCY_KEY_REUSED.
  • A request that failed can be corrected and sent again with the same key.

Reference

Error Codes

Every error has the same shape: a code to act on, a message to show a person, details naming fields where that helps, and a requestId to quote if you contact us.

Example · 401 Unauthorized

JSON
{
  "error": {
    "code": "UNAUTHENTICATED",
    "message": "An API key is required. Send it as: Authorization: Bearer <key>",
    "requestId": "req_8f14e45f-ceea-467a-9575-5a3c1c2f3a1b",
    "details": []
  }
}
StatusCodeWhat it means
400VALIDATION_FAILEDA field is the wrong type or too long, a field name is not recognised, or a value is out of range. details names each field.
400LISTING_INCOMPLETECreate Business or Submit for Review is missing required details. Nothing was created; details lists every missing field.
400UNKNOWN_CATEGORYA category code is not in Categories.
401UNAUTHENTICATEDNo API key, or a key that is wrong or has been rotated.
402PLAN_LIMIT_REACHEDMore FAQs than the business’s plan allows (5 on Free, 25 on Pro and Scale).
403API_KEY_OWNER_GONEThe person who made the key is no longer the account’s owner. Make a new key in the dashboard.
404BUSINESS_NOT_FOUNDNot a business on this account. Another account’s business answers the same.
404POST_NOT_FOUNDNot a post of this business.
404IMAGE_NOT_FOUNDNot an image of this business.
409LISTING_NOT_LIVEOnly a live (active) business can be deactivated.
409LISTING_NOT_DEACTIVATEDReactivate only switches back on a business you deactivated.
409LISTING_PAUSED_BY_REVIEWOur review team paused this business. Contact support.
409LISTING_INVALID_STATEThe business cannot do that from its current status, for example submitting one that is already live.
409POST_HELD_FOR_REVIEWThe post is being checked by our team and cannot be changed yet. See Content check.
409POST_ALREADY_PUBLISHEDThe post is already published.
409POST_NOT_PUBLISHEDThe post is not published, so there is nothing to take down.
409IMAGE_LIMIT_REACHEDThe business already has its logo, or its 10 photos. Delete one first.
409MEDIA_NOT_UPLOADEDComplete was called before the file was sent to the upload URL.
409MEDIA_HELD_FOR_REVIEWThe image is being checked by our team and cannot be used as a cover yet.
409IDEMPOTENCY_KEY_REUSEDThe same Idempotency-Key was sent with a different body.
409IDEMPOTENCY_IN_PROGRESSThe first request with this Idempotency-Key is still running. Retry shortly.
413MEDIA_TOO_LARGEThe file is over the size limit for its type. It was deleted.
422MEDIA_REJECTEDThe file is not a PNG, JPG or WEBP image. It was deleted.
422MEDIA_EMPTYThe file was empty. It was deleted.
429API_QUOTA_EXCEEDEDThis month’s 10,000 requests are used. The message gives the reset date.
429RATE_LIMITEDOver 120 requests in a minute with one key. Wait a moment and retry.
500INTERNAL_ERROROur fault. Retry; if it continues, send us the requestId.

Get started

Ready to get discovered?

Start getting recommended by AI platforms today.
No setup fees, no contracts.

  • Free tier available
  • 5-minute setup