openapi: 3.1.0 info: title: Bit - URL Shortener API description: A high-performance URL shortener service with click tracking and analytics version: 1.0.0 contact: name: API Support url: https://github.com/sjdonado/bit servers: - url: http://localhost:4000 description: Development server - url: http://localhost:4001 description: Benchmark server security: - ApiKeyAuth: [] paths: /api/ping: get: summary: Ping the API description: Health check endpoint to verify the API is running operationId: ping tags: - Health security: [] responses: '200': description: API is healthy content: application/json: schema: type: object properties: data: type: string example: pong /{slug}: get: summary: Redirect by slug description: Redirects to the original URL and tracks the click asynchronously operationId: redirectBySlug tags: - Redirects security: [] parameters: - name: slug in: path required: true description: The short URL slug schema: type: string example: 3wP4BQ - name: utm_source in: query required: false description: UTM source parameter for tracking schema: type: string example: email_campaign responses: '301': description: Redirect to original URL headers: Location: description: The original URL schema: type: string example: https://example.com X-Forwarded-For: description: Client IP address schema: type: string User-Agent: description: User agent string schema: type: string '404': description: Link not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/links: get: summary: List all links description: Retrieve all links for the authenticated user with pagination support operationId: listLinks tags: - Links parameters: - name: limit in: query description: Number of results per page schema: type: integer default: 100 minimum: 1 maximum: 1000 - name: cursor in: query description: Pagination cursor from previous response schema: type: string responses: '200': description: List of links content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/LinkSummary' pagination: $ref: '#/components/schemas/Pagination' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' post: summary: Create new link description: Create a new shortened link operationId: createLink tags: - Links requestBody: required: true content: application/json: schema: type: object required: - url properties: url: type: string format: uri description: The URL to shorten example: https://example.com responses: '201': description: Link created successfully content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Link' '400': description: Bad request - invalid URL or missing field content: application/json: schema: $ref: '#/components/schemas/Error' examples: missingField: value: error: "url: Required field" invalidUrl: value: errors: url: - is invalid '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' /api/links/{id}: get: summary: Get link by ID description: Retrieve a specific link with up to 100 most recent clicks. For complete click history, use /api/links/{id}/clicks operationId: getLink tags: - Links parameters: - name: id in: path required: true description: Link ID schema: type: integer format: int64 responses: '200': description: Link details content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Link' '404': description: Link not found content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' put: summary: Update link description: Update the URL of an existing link operationId: updateLink tags: - Links parameters: - name: id in: path required: true description: Link ID schema: type: integer format: int64 requestBody: required: true content: application/json: schema: type: object required: - url properties: url: type: string format: uri description: The new URL example: https://newexample.com responses: '200': description: Link updated successfully content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Link' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Forbidden - link belongs to another user content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Link not found content: application/json: schema: $ref: '#/components/schemas/Error' delete: summary: Delete link description: Delete a link and all its associated clicks operationId: deleteLink tags: - Links parameters: - name: id in: path required: true description: Link ID schema: type: integer format: int64 responses: '204': description: Link deleted successfully '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Forbidden - link belongs to another user content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Link not found content: application/json: schema: $ref: '#/components/schemas/Error' /api/links/{id}/clicks: get: summary: List clicks for a link description: Retrieve all clicks for a specific link with pagination support operationId: listClicks tags: - Clicks parameters: - name: id in: path required: true description: Link ID schema: type: integer format: int64 - name: limit in: query description: Number of results per page schema: type: integer default: 100 minimum: 1 maximum: 1000 - name: cursor in: query description: Pagination cursor from previous response schema: type: string responses: '200': description: List of clicks content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/Click' pagination: $ref: '#/components/schemas/Pagination' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Link not found content: application/json: schema: $ref: '#/components/schemas/Error' components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-Api-Key description: API key for authentication schemas: LinkSummary: type: object properties: id: type: integer format: int64 description: Unique link identifier example: 1 refer: type: string format: uri description: The shortened URL example: http://localhost:4000/3wP4BQ origin: type: string format: uri description: The original URL example: https://monocuco.donado.co Link: allOf: - $ref: '#/components/schemas/LinkSummary' - type: object properties: clicks: type: array description: Array of click records (up to 100 most recent) items: $ref: '#/components/schemas/Click' Click: type: object properties: id: type: integer format: int64 description: Unique click identifier example: 1 user_agent: type: string description: User agent string example: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:127.0) Gecko/20100101 Firefox/127.0 country: type: string nullable: true description: Country code (ISO 3166-1 alpha-2) example: US browser: type: string nullable: true description: Browser name example: Firefox os: type: string nullable: true description: Operating system example: Mac OS X referer: type: string nullable: true description: Referer domain or utm_source example: Direct created_at: type: string format: date-time description: Click timestamp example: 2024-07-12T19:25:22Z Pagination: type: object properties: has_more: type: boolean description: Whether there are more results example: true next: type: integer format: int64 nullable: true description: Cursor for next page (link/click ID) example: 12 Error: type: object properties: error: type: string description: Error message example: Resource not found required: - error ValidationErrors: type: object properties: errors: type: object additionalProperties: type: array items: type: string description: Field-level validation errors example: url: - is invalid tags: - name: Health description: Health check endpoints - name: Redirects description: URL redirection and click tracking - name: Links description: Link management operations - name: Clicks description: Click analytics and tracking