{"openapi":"3.1.0","info":{"title":"Indie Chains API","version":"1.0.0","description":"Public discovery and authenticated member operations for Indie Chains, a reviewed collaboration network for independent founders and site operators. Indie Chains sells software access; it does not sell links or guarantee publication or SEO outcomes.","contact":{"name":"Indie Chains support","email":"hello@indiechains.com","url":"https://www.indiechains.com/contact"},"license":{"name":"Proprietary — see Terms of Service","url":"https://www.indiechains.com/terms"}},"externalDocs":{"description":"Indie Chains developer and agent documentation","url":"https://www.indiechains.com/developers"},"servers":[{"url":"https://api.indiechains.com","description":"Production API"}],"tags":[{"name":"System","description":"Service availability."},{"name":"Discovery","description":"Public site and network discovery."},{"name":"Metrics","description":"Public website metric checks."},{"name":"Membership","description":"Public membership offer information."},{"name":"Reviews","description":"Approved public member reviews."},{"name":"Authentication","description":"Account authentication and identity."}],"paths":{"/health":{"get":{"operationId":"getServiceHealth","summary":"Check API health","description":"Returns a lightweight process health signal. This endpoint does not check database readiness.","tags":["System"],"responses":{"200":{"description":"The API process is healthy.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["status","service"],"properties":{"status":{"type":"string","const":"ok"},"service":{"type":"string"}}}}}}}}},"/sites":{"get":{"operationId":"listPublicSites","summary":"List approved public sites","description":"Returns approved Indie Chains sites in reverse chronological order with pagination and available categories.","tags":["Discovery"],"parameters":[{"name":"category","in":"query","required":false,"description":"Return only sites in this exact category.","schema":{"type":"string","minLength":1,"maxLength":80}},{"name":"page","in":"query","required":false,"description":"One-based result page.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","required":false,"description":"Maximum sites returned per page.","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"A page of approved sites.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["sites","pagination","categories"],"properties":{"sites":{"type":"array","items":{"type":"object","description":"A public, approved Indie Chains site summary.","required":["id","slug","name","url","category"],"properties":{"id":{"type":"string","description":"Stable Indie Chains record identifier."},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"name":{"type":"string"},"url":{"type":"string","format":"uri"},"tagline":{"type":["string","null"]},"category":{"type":"string"},"domainRating":{"type":["number","null"],"minimum":0,"maximum":100},"logoUrl":{"type":["string","null"],"format":"uri-reference"}}}},"pagination":{"type":"object","required":["page","limit","total","hasNextPage"],"properties":{"page":{"type":"integer","minimum":1},"limit":{"type":"integer","minimum":1},"total":{"type":"integer","minimum":0},"hasNextPage":{"type":"boolean"}}},"categories":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Invalid query parameters.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/sites/{slug}":{"get":{"operationId":"getPublicSiteBySlug","summary":"Get an approved public site","description":"Returns public details for one approved site identified by its Indie Chains slug.","tags":["Discovery"],"parameters":[{"name":"slug","in":"path","required":true,"description":"The stable Indie Chains site slug.","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"}}],"responses":{"200":{"description":"Public site details.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["site"],"properties":{"site":{"type":"object","description":"A public, approved Indie Chains site summary.","required":["id","slug","name","url","category"],"properties":{"id":{"type":"string","description":"Stable Indie Chains record identifier."},"slug":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"name":{"type":"string"},"url":{"type":"string","format":"uri"},"tagline":{"type":["string","null"]},"category":{"type":"string"},"domainRating":{"type":["number","null"],"minimum":0,"maximum":100},"logoUrl":{"type":["string","null"],"format":"uri-reference"}}}}}}}},"404":{"description":"No approved public site has this slug.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/sites/domain-rating-check":{"post":{"operationId":"checkPublicDomainRating","summary":"Check a public domain's Domain Rating","description":"Normalizes a public URL and returns the latest available Ahrefs Domain Rating. This rate-limited endpoint does not guarantee that a score is available.","tags":["Metrics"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","format":"uri","maxLength":2048}}},"example":{"url":"https://example.com"}}}},"responses":{"200":{"description":"The latest available Domain Rating result.","content":{"application/json":{"schema":{"type":"object","required":["domain","url","faviconUrl","domainRating","checkedAt"],"properties":{"domain":{"type":"string","format":"hostname"},"url":{"type":"string","format":"uri"},"faviconUrl":{"type":"string","format":"uri"},"domainRating":{"type":"number","minimum":0,"maximum":100},"checkedAt":{"type":"string","format":"date-time"}}}}}},"400":{"description":"The URL is invalid or cannot be checked.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"429":{"description":"The rate limit has been exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"502":{"description":"The metrics provider did not return a score.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/billing/tiers":{"get":{"operationId":"getMembershipTiers","summary":"Get current membership offers","description":"Returns the current public membership tier, approved-site count, optional lifetime offer, and the included offer details. Verify prices immediately before presenting them to a user.","tags":["Membership"],"responses":{"200":{"description":"Current public membership information.","content":{"application/json":{"schema":{"type":"object","required":["approvedSiteCount","activeTier","tiers"],"properties":{"approvedSiteCount":{"type":"integer","minimum":0},"activeTier":{"$ref":"#/components/schemas/MembershipTier"},"tiers":{"type":"array","items":{"$ref":"#/components/schemas/MembershipTier"}},"lifetime":{"oneOf":[{"$ref":"#/components/schemas/LifetimeOffer"},{"type":"null"}]},"offer":{"type":"object","additionalProperties":true}}}}}},"503":{"description":"Membership information is temporarily unavailable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/member-reviews/public":{"get":{"operationId":"listPublicMemberReviews","summary":"List approved member reviews","description":"Returns reviews that passed moderation and are approved for public display.","tags":["Reviews"],"responses":{"200":{"description":"Approved public reviews.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["reviews"],"properties":{"reviews":{"type":"array","items":{"type":"object","required":["id","rating","body","user"],"properties":{"id":{"type":"string","description":"Stable Indie Chains review identifier."},"rating":{"type":"integer","minimum":1,"maximum":5},"body":{"type":"string"},"destinationUrl":{"type":["string","null"],"format":"uri"},"user":{"type":"object","required":["username"],"properties":{"username":{"type":"string"},"displayName":{"type":["string","null"]},"avatarUrl":{"type":["string","null"],"format":"uri-reference"}}}}}}}}}}}}}},"/auth/register":{"post":{"operationId":"registerAccount","summary":"Register an account","description":"Creates an Indie Chains account and returns a bearer token. Do not call this operation without the user's explicit intent to create an account.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationCredentials"}}}},"responses":{"200":{"description":"Credentials were added to an existing OAuth account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResult"}}}},"201":{"description":"The account was created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResult"}}}},"400":{"description":"The registration details are invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"409":{"description":"An account already exists for this email.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"429":{"description":"The rate limit has been exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/auth/login":{"post":{"operationId":"loginWithEmailPassword","summary":"Authenticate with email and password","description":"Authenticates an existing account and returns a bearer token. Treat the token as a secret.","tags":["Authentication"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailPasswordCredentials"}}}},"responses":{"200":{"description":"Authentication succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResult"}}}},"400":{"description":"The credentials are malformed.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"401":{"description":"The credentials are invalid.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}},"429":{"description":"The rate limit has been exceeded.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}},"/auth/me":{"get":{"operationId":"getAuthenticatedAccount","summary":"Get the authenticated account","description":"Returns the account associated with the supplied bearer token.","tags":["Authentication"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The authenticated account.","content":{"application/json":{"schema":{"type":"object","required":["user"],"properties":{"user":{"$ref":"#/components/schemas/User"}}}}}},"401":{"description":"A valid bearer token is required.","content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","description":"Human-readable error message."}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT returned by the Indie Chains login or registration operation."}},"schemas":{"MembershipTier":{"type":"object","additionalProperties":false,"required":["name","label","approvedSiteMin","monthlyPriceCents","currency"],"properties":{"name":{"type":"string"},"label":{"type":"string"},"approvedSiteMin":{"type":"integer","minimum":0},"approvedSiteMax":{"type":["integer","null"],"minimum":0},"monthlyPriceCents":{"type":"integer","minimum":0},"currency":{"type":"string","pattern":"^[A-Z]{3}$"}}},"LifetimeOffer":{"type":"object","required":["regularPriceCents","launchPriceCents","activePriceCents","currency","checkoutReady"],"properties":{"regularPriceCents":{"type":"integer","minimum":0},"launchPriceCents":{"type":"integer","minimum":0},"activePriceCents":{"type":"integer","minimum":0},"launchApprovedSiteMax":{"type":"integer","minimum":0},"currency":{"type":"string","pattern":"^[A-Z]{3}$"},"checkoutReady":{"type":"boolean"}}},"EmailPasswordCredentials":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","maxLength":320},"password":{"type":"string","format":"password","minLength":8,"maxLength":200}}},"RegistrationCredentials":{"allOf":[{"$ref":"#/components/schemas/EmailPasswordCredentials"},{"type":"object","required":["username"],"properties":{"username":{"type":"string","minLength":3,"maxLength":32,"pattern":"^[A-Za-z0-9_-]+$"}}}]},"AuthResult":{"type":"object","required":["token","user"],"properties":{"token":{"type":"string","description":"Bearer token. Store and transmit it securely."},"user":{"$ref":"#/components/schemas/User"}}},"User":{"type":"object","required":["id","email","username"],"properties":{"id":{"type":"string","description":"Stable Indie Chains user identifier."},"email":{"type":"string","format":"email"},"username":{"type":"string"},"displayName":{"type":["string","null"]},"avatarUrl":{"type":["string","null"],"format":"uri-reference"}}}}}}