{ "openapi": "3.0.1", "info": { "title": "Acme API", "version": "1.0.1" }, "servers": [ { "url": "http://localhost:3000/api/v1" } ], "tags": [ { "name": "Auth" }, { "name": "Articles" }, { "name": "Others" } ], "paths": { "/registrations": { "post": { "tags": [ "Auth" ], "summary": "Registration", "description": "Attempts to register a new user in the system. Email address must be unique.\nIf registration succeeds an authentication token is returned. Use this token\nto authenticate requests with the header `Authorization: Bearer \u003Ctoken\u003E`.\n", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "description": "Full name\n\n* Must not be empty", "type": "string", "minLength": 1 }, "email_address": { "description": "Email address used to login. Case insensitive.\n\n* Case insensitive", "type": "string", "pattern": "\\A[a-zA-Z0-9.!\\#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\\z" }, "password": { "description": "Minimum 8 characters. No other rules.", "type": "string", "minLength": 8 }, "terms_of_use": { "description": "* Must be accepted (true)", "type": "boolean" } }, "required": [ "name", "email_address", "password", "terms_of_use" ] }, "examples": { "0": { "value": { "name": "Luiz", "email_address": "luiz@example.org", "password": "mystrongpassword", "terms_of_use": true } }, "1": { "value": { "name": "Yukihiro Matsumoto", "email_address": "matz@ruby.org", "password": "mystrongpassword#'\"", "terms_of_use": true } } } } }, "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string" } }, "required": [ "token" ] }, "examples": { "0": { "value": { "token": "62JwTHviDTCK4QYWa2gs" } } } } }, "description": "OK" }, "422": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object", "properties": { "error": { "type": "string", "enum": [ "email_already_taken" ] } }, "required": [ "error" ] }, { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } ] }, "examples": { "0": { "value": { "error": "email_already_taken" } }, "1": { "value": { "error": "invalid_params", "params": { "name": "must be a string", "email_address": "must be a string", "password": "must be a string", "terms_of_use": "must be accepted" } } } } } }, "description": "Unprocessable Content" } } } }, "/sessions": { "post": { "tags": [ "Auth" ], "summary": "Log in", "description": "Attempts to sign in a user to the system. If sign in succeeds an\nauthentication token is returned. Use this token to authenticate requests\nwith the header `Authorization: Bearer \u003Ctoken\u003E`.\n", "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "email_address": { "description": "* Case insensitive", "type": "string", "pattern": "\\A[a-zA-Z0-9.!\\#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\\z" }, "password": { "type": "string", "minLength": 8 } }, "required": [ "email_address", "password" ] }, "examples": { "0": { "value": { "email_address": "non-existing-user@example.org", "password": "any-password" } }, "1": { "value": { "email_address": "luiz@example.org", "password": "wrong-password" } }, "2": { "value": { "email_address": "luiz@example.org", "password": "mystrongpassword" } } } } }, "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "token": { "type": "string" } }, "required": [ "token" ] }, "examples": { "0": { "value": { "token": "HjO0krVQDjwDSDY0XRZM" } } } } }, "description": "OK" }, "422": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_credentials" ] } }, "required": [ "error" ] }, { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } ] }, "examples": { "0": { "value": { "error": "invalid_credentials" } }, "1": { "value": { "error": "invalid_params", "params": { "email_address": "must be a string", "password": "must be a string" } } }, "2": { "value": { "error": "invalid_credentials" } } } } }, "description": "Unprocessable Content" } } }, "delete": { "tags": [ "Auth" ], "summary": "Log out", "description": "Revokes the authentication token used to authenticate the request, which\nprevents the token from being used in the future.\n", "parameters": [ { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string", "pattern": "Bearer [a-zA-Z0-9]{20}" }, "style": "simple" } ], "responses": { "403": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "unauthorized" ] } }, "required": [ "error" ] } } }, "description": "Forbidden" }, "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "enum": [ "session revoked" ] } }, "required": [ "message" ] } } }, "description": "OK" } } } }, "/articles": { "post": { "tags": [ "Articles" ], "summary": "Create article", "parameters": [ { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string", "pattern": "Bearer [a-zA-Z0-9]{20}" }, "style": "simple" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "content": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "published_at": { "description": "* Must be valid according to ISO 8601", "type": "string", "format": "date-time" } }, "required": [ "title", "content" ] }, "examples": { "0": { "value": { "title": "Article title", "content": "Article content", "published_at": null } }, "1": { "value": { "title": "Article title", "content": "Article content", "published_at": "2025-01-12T17:26:52.000Z" } } } } }, "required": true }, "responses": { "403": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "unauthorized" ] } }, "required": [ "error" ] } } }, "description": "Forbidden" }, "201": { "content": { "application/json": { "schema": { "type": "object", "properties": { "article": { "type": "object", "properties": { "id": { "description": "* Must not be negative", "type": "integer" }, "title": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "content": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "published_at": { "description": "* When published_at is null it means the article is a draft.\n* When published_at is a moment in the future it means the article\n is scheduled to be published.\n* When published_at is a moment in the past it means the article is\n published and can be read by everyone.\n\n\n* Must be valid according to ISO 8601", "type": "string", "format": "date-time" }, "read_count": { "description": "* Must be positive", "type": "integer" } }, "required": [ "id", "title", "content", "read_count" ] } }, "required": [ "article" ] }, "examples": { "0": { "value": { "article": { "id": 594821791, "title": "Article title", "content": "Article content", "published_at": null, "read_count": 0 } } }, "1": { "value": { "article": { "id": 594821791, "title": "Article title", "content": "Article content", "published_at": "2025-01-12T17:26:52.000Z", "read_count": 0 } } } } } }, "description": "Created" }, "422": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } } }, "description": "Unprocessable Content" } } } }, "/articles/{article_id}": { "get": { "tags": [ "Articles" ], "summary": "Get article", "parameters": [ { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string", "pattern": "Bearer [a-zA-Z0-9]{20}" }, "style": "simple" }, { "name": "article_id", "in": "path", "required": true, "schema": { "description": "* Must be positive", "type": "integer" }, "style": "simple" } ], "responses": { "403": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "unauthorized" ] } }, "required": [ "error" ] }, "examples": { "0": { "value": { "error": "unauthorized" } } } } }, "description": "Forbidden" }, "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "article": { "type": "object", "properties": { "id": { "description": "* Must not be negative", "type": "integer" }, "title": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "content": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "published_at": { "description": "* When published_at is null it means the article is a draft.\n* When published_at is a moment in the future it means the article\n is scheduled to be published.\n* When published_at is a moment in the past it means the article is\n published and can be read by everyone.\n\n\n* Must be valid according to ISO 8601", "type": "string", "format": "date-time" }, "read_count": { "description": "* Must be positive", "type": "integer" } }, "required": [ "id", "title", "content", "read_count" ] } }, "required": [ "article" ] }, "examples": { "0": { "value": { "article": { "id": 594821790, "title": "Title", "content": "Content", "published_at": "2025-01-12T17:26:52.000Z", "read_count": 0 } } } } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "object" }, "examples": { "0": { "value": { } } } } }, "description": "Not Found" }, "422": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } } }, "description": "Unprocessable Content" } } }, "put": { "tags": [ "Articles" ], "summary": "Update article", "parameters": [ { "name": "Authorization", "in": "header", "required": true, "schema": { "type": "string", "pattern": "Bearer [a-zA-Z0-9]{20}" }, "style": "simple" }, { "name": "article_id", "in": "path", "required": true, "schema": { "description": "* Must be positive", "type": "integer" }, "style": "simple" } ], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "title": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "content": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "published_at": { "description": "* Must be valid according to ISO 8601", "type": "string", "format": "date-time" } }, "required": [ "title", "content" ] }, "examples": { "0": { "value": { "title": "Updated title", "content": "Updated content", "published_at": null } }, "1": { "value": { "title": "Updated title", "content": "Updated content", "published_at": null } }, "2": { "value": { "title": "Updated Title", "content": "Updated Content", "published_at": "2025-01-12T17:26:52.000Z" } }, "3": { "value": { "title": "Title", "content": "Content", "published_at": null } } } } }, "required": true }, "responses": { "403": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "unauthorized" ] } }, "required": [ "error" ] }, "examples": { "0": { "value": { "error": "unauthorized" } } } } }, "description": "Forbidden" }, "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "article": { "type": "object", "properties": { "id": { "description": "* Must not be negative", "type": "integer" }, "title": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "content": { "description": "* Must not be empty", "type": "string", "minLength": 1 }, "published_at": { "description": "* When published_at is null it means the article is a draft.\n* When published_at is a moment in the future it means the article\n is scheduled to be published.\n* When published_at is a moment in the past it means the article is\n published and can be read by everyone.\n\n\n* Must be valid according to ISO 8601", "type": "string", "format": "date-time" }, "read_count": { "description": "* Must be positive", "type": "integer" } }, "required": [ "id", "title", "content", "read_count" ] } }, "required": [ "article" ] }, "examples": { "0": { "value": { "article": { "title": "Updated Title", "content": "Updated Content", "published_at": "2025-01-12T17:26:52.000Z", "id": 594821790, "read_count": 0 } } }, "1": { "value": { "article": { "title": "Title", "content": "Content", "published_at": null, "id": 594821790, "read_count": 0 } } } } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "object" }, "examples": { "0": { "value": { } } } } }, "description": "Not Found" }, "422": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } } }, "description": "Unprocessable Content" } } } }, "/everything": { "post": { "tags": [ "Others" ], "summary": "Everything", "description": "This request uses all available types in the Explicit gem to showcase and\ntest them.\n", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "file1": { "description": "* Max size: 2 MB\n* Content types: image/jpeg, image/png", "type": "string", "format": "binary" }, "string1": { "default": "Foo", "description": "* Must not be empty", "type": "string", "minLength": 1, "maxLength": 100 }, "integer1": { "default": 5, "type": "integer", "minimum": 1, "maximum": 100 }, "hash1": { "type": "object", "additionalProperties": { "description": "A description of the hash values", "type": "array", "items": { "type": "integer", "minimum": 0, "maximum": 10 }, "minItems": 0 } }, "agreement1": { "description": "* Must be accepted (true)", "type": "boolean" }, "big_decimal1": { "description": "* Minimum: 0\n* Maximum: 100", "type": "string", "pattern": "^\\d*\\.?\\d*$", "format": "decimal number" }, "boolean1": { "type": "boolean" }, "date1": { "type": "string", "pattern": "\\d{4}-\\d{2}-\\d{2}", "format": "date", "description_topics": [ "Translation missing: en.explicit.swagger.date_format" ] }, "date_range1": { "description": "* The value must be a range between two dates in the format of: \"YYYY-MM-DD..YYYY-MM-DD\"\n* The range must not be less than 1 day\n* The range must not be more than 30 days", "type": "string", "pattern": "^(\\d{4}-\\d{2}-\\d{2})\\.\\.(\\d{4}-\\d{2}-\\d{2})$", "format": "date range" }, "date_time_iso8601_range": { "description": "* The value must be a range between two date times in the format of: \"YYYY-MM-DDTHH:MM:SS..YYYY-MM-DDTHH:MM:SS\"\n* The range must not be less than 1 hour\n* The range must not be more than 24 hours", "type": "string", "format": "date time range" }, "date_time_iso8601": { "description": "* Must be valid according to ISO 8601", "type": "string", "format": "date-time" }, "date_time_unix_epoch": { "description": "* POSIX time or Unix epoch is the amount of seconds since 1970-01-01", "type": "integer", "minimum": 1, "format": "POSIX time" }, "enum1": { "type": "string", "enum": [ "one", "two", "three" ] } }, "required": [ "file1", "string1", "integer1", "hash1", "agreement1", "big_decimal1", "boolean1", "date1", "date_range1", "date_time_iso8601_range", "date_time_iso8601", "date_time_unix_epoch", "enum1" ] } } }, "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "type": "object", "properties": { "message": { "type": "string", "enum": [ "ok" ] } }, "required": [ "message" ] }, "examples": { "0": { "value": { "message": "ok" } } } } }, "description": "OK" }, "422": { "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string", "enum": [ "invalid_params" ] }, "params": { "description": "An object containing error messages for all invalid params", "type": "object", "additionalProperties": { "type": "string" } } }, "required": [ "error", "params" ] } } }, "description": "Unprocessable Content" } } } } } }