{
  "openapi": "3.1.0",
  "info": {
    "title": "Neeblo | Innovative IT Solutions & Digital Transformation Services public API",
    "summary": "Public endpoints of www.neeblo.com: form submissions and machine-readable site files.",
    "description": "Public endpoints of https://www.neeblo.com. No authentication is needed. Requests are rate limited per client IP; every API response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset headers and a 429 carries Retry-After. Errors are JSON for `Accept: application/json`, Markdown for `Accept: text/markdown`.",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://www.neeblo.com"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "forms",
      "description": "Submissions that land in the website owner's inbox."
    },
    {
      "name": "files",
      "description": "Machine-readable site files."
    }
  ],
  "paths": {
    "/submit-contacts": {
      "post": {
        "operationId": "submitContact",
        "tags": [
          "forms"
        ],
        "summary": "Send a contact message",
        "description": "Stores a contact form message for the website owner. Every field whose name starts with `form_` is kept as the message detail. One submission per client IP is accepted at a time; more get 429.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactForm"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/ContactForm"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The message was stored.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string",
                  "example": "Success!"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be understood or a required field is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "The server failed to handle the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/submit-leads": {
      "post": {
        "operationId": "submitLead",
        "tags": [
          "forms"
        ],
        "summary": "Answer a lead form",
        "description": "Stores the answers to a lead form of the website. The lead is named with `form_lead_id` or `form_lead_uuid`; the answers go in `leads_submit_detail` keyed by field. Use multipart/form-data to attach files.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadSubmit"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/LeadSubmit"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The answers were stored.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string",
                  "example": "Success!"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be understood or a required field is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "The server failed to handle the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/submit-comments": {
      "post": {
        "operationId": "submitComment",
        "tags": [
          "forms"
        ],
        "summary": "Comment on an article",
        "description": "Stores a comment on an article. It is unpublished until the website owner approves it. `form_name` and `form_text` are required; the article is named with `form_article_id` or `form_article_uuid`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CommentForm"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/CommentForm"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The comment was stored (or the reply names the missing field).",
            "headers": {
              "RateLimit-Limit": {
                "description": "Requests allowed per window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the window resets.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "text/html": {
                "schema": {
                  "type": "string",
                  "example": "Success!"
                }
              }
            }
          },
          "400": {
            "description": "The request could not be understood or a required field is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "The server failed to handle the request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/sitemap.xml": {
      "get": {
        "operationId": "getSitemap",
        "tags": [
          "files"
        ],
        "summary": "Sitemap",
        "description": "The sitemap of the website in the sitemaps.org XML format.",
        "responses": {
          "200": {
            "description": "Sitemap XML.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/rss.xml": {
      "get": {
        "operationId": "getRssFeed",
        "tags": [
          "files"
        ],
        "summary": "RSS feed",
        "description": "The latest articles of the website as an RSS feed.",
        "responses": {
          "200": {
            "description": "RSS XML.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "tags": [
          "files"
        ],
        "summary": "llms.txt",
        "description": "What the website offers and when an agent should use it, in the llms.txt format.",
        "responses": {
          "200": {
            "description": "Plain text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/llms-full.txt": {
      "get": {
        "operationId": "getLlmsFullTxt",
        "tags": [
          "files"
        ],
        "summary": "llms-full.txt",
        "description": "The full text version of llms.txt with the content of the website.",
        "responses": {
          "200": {
            "description": "Plain text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/robots.txt": {
      "get": {
        "operationId": "getRobotsTxt",
        "tags": [
          "files"
        ],
        "summary": "robots.txt",
        "description": "Crawl rules of the website.",
        "responses": {
          "200": {
            "description": "Plain text.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "404": {
            "description": "The requested resource does not exist.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "tags": [
          "files"
        ],
        "summary": "This OpenAPI document",
        "description": "The OpenAPI 3.1 description of the public endpoints of this website.",
        "responses": {
          "200": {
            "description": "OpenAPI JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Every error an agent can parse.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "status",
              "code",
              "message",
              "resolution"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "The HTTP status."
              },
              "code": {
                "type": "string",
                "description": "Stable machine-readable code.",
                "enum": [
                  "bad_request",
                  "forbidden",
                  "internal_error",
                  "method_not_allowed",
                  "not_found",
                  "payload_too_large",
                  "rate_limited",
                  "unauthorized"
                ]
              },
              "message": {
                "type": "string",
                "description": "What went wrong."
              },
              "resolution": {
                "type": "string",
                "description": "What to do about it."
              },
              "docs": {
                "type": "string",
                "description": "Where the endpoints are described."
              },
              "path": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The path that failed."
              }
            }
          }
        }
      },
      "ContactForm": {
        "type": "object",
        "description": "A contact message: any `form_*` fields.",
        "additionalProperties": {
          "type": "string"
        },
        "properties": {
          "form_name": {
            "type": "string",
            "description": "Name of the sender."
          },
          "form_email": {
            "type": "string",
            "format": "email",
            "description": "E-mail of the sender."
          },
          "form_message": {
            "type": "string",
            "description": "The message."
          },
          "form_utm": {
            "type": "string",
            "description": "Campaign tag."
          },
          "form_language": {
            "type": "string",
            "description": "Language code of the sender."
          }
        }
      },
      "LeadSubmit": {
        "type": "object",
        "description": "The answers to a lead form.",
        "properties": {
          "form_lead_id": {
            "type": "integer",
            "description": "Numeric id of the lead form."
          },
          "form_lead_uuid": {
            "type": "string",
            "description": "UUID of the lead form."
          },
          "leads_submit_detail": {
            "type": "object",
            "description": "Answers keyed by the lead field name.",
            "additionalProperties": true
          },
          "form_utm": {
            "type": "string",
            "description": "Campaign tag."
          },
          "form_language": {
            "type": "string",
            "description": "Language code of the sender."
          }
        }
      },
      "CommentForm": {
        "type": "object",
        "description": "A comment on an article.",
        "required": [
          "form_name",
          "form_text"
        ],
        "properties": {
          "form_name": {
            "type": "string",
            "minLength": 1,
            "description": "Name of the commenter."
          },
          "form_text": {
            "type": "string",
            "minLength": 1,
            "description": "The comment."
          },
          "form_email": {
            "type": "string",
            "format": "email",
            "description": "E-mail of the commenter."
          },
          "form_href": {
            "type": "string",
            "format": "uri",
            "description": "Page the comment was written on."
          },
          "form_article_id": {
            "type": "integer",
            "description": "Numeric id of the article."
          },
          "form_article_uuid": {
            "type": "string",
            "description": "UUID of the article."
          },
          "form_utm": {
            "type": "string",
            "description": "Campaign tag."
          },
          "form_language": {
            "type": "string",
            "description": "Language code of the commenter."
          }
        }
      }
    }
  }
}