{
  "openapi": "3.0.3",
  "info": {
    "title": "businesscards.io Tools API",
    "description": "Free public API for business card design tools. No authentication required.",
    "version": "1.0.0",
    "contact": {
      "name": "businesscards.io",
      "url": "https://businesscards.io/tools/api"
    }
  },
  "servers": [
    {
      "url": "https://businesscards.io",
      "description": "Production"
    }
  ],
  "paths": {
    "/tools/api/business-card-size-check": {
      "post": {
        "summary": "Check business card size and print quality",
        "description": "Upload a business card image to check if it meets standard print dimensions (US, EU, Japanese). Returns image dimensions, aspect ratio matching, estimated DPI, and print quality assessment. Rate limited to 2 requests per second per IP.",
        "operationId": "checkBusinessCardSize",
        "tags": ["Business Card Tools"],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": ["image"],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "Business card image file. Accepted formats: PNG, JPEG, WebP, TIFF. Maximum size: 25 MB. Maximum dimensions: 50,000 pixels per side."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful analysis",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SizeCheckResult"
                },
                "example": {
                  "file_name": "my-card.png",
                  "file_size_bytes": 2457600,
                  "width_px": 1050,
                  "height_px": 600,
                  "aspect_ratio": 1.75,
                  "standards": [
                    {
                      "name": "US Standard",
                      "dimensions": "3.5\" × 2\"",
                      "aspect_ratio_match": true,
                      "estimated_dpi": 300,
                      "status": "perfect_match"
                    },
                    {
                      "name": "EU / ISO 7810",
                      "dimensions": "85mm × 55mm",
                      "aspect_ratio_match": false,
                      "estimated_dpi": 277,
                      "status": "aspect_ratio_mismatch"
                    },
                    {
                      "name": "Japanese",
                      "dimensions": "91mm × 55mm",
                      "aspect_ratio_match": false,
                      "estimated_dpi": 269,
                      "status": "aspect_ratio_mismatch"
                    }
                  ],
                  "print_quality": {
                    "estimated_dpi": 300,
                    "print_ready": true,
                    "high_quality": false,
                    "minimum_usable": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing image, invalid file type, file too large, or corrupt image",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missing_image": {
                    "value": { "error": "Missing required parameter: image" }
                  },
                  "invalid_type": {
                    "value": { "error": "Invalid file type. Accepted: PNG, JPEG, WebP, TIFF" }
                  },
                  "too_large": {
                    "value": { "error": "File too large. Maximum size: 25 MB" }
                  },
                  "dimensions_too_large": {
                    "value": { "error": "Image dimensions too large. Maximum: 50,000 pixels per side." }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (2 requests per second per IP)",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "example": "Retry later\n"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            }
          }
        }
      }
    },
    "/tools/api/vcard-generate": {
      "post": {
        "summary": "Generate a vCard (.vcf) file",
        "description": "Generate a vCard 3.0 file from contact information. Returns the vCard string and a suggested filename. Rate limited to 2 requests per second per IP.",
        "operationId": "generateVcard",
        "tags": ["Business Card Tools"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VcardGenerateRequest"
              },
              "example": {
                "first_name": "John",
                "last_name": "Doe",
                "email": "john@example.com",
                "phone": "+1-555-0123",
                "company": "Acme Corp",
                "title": "CEO"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successfully generated vCard",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VcardGenerateResult"
                },
                "example": {
                  "vcard": "BEGIN:VCARD\r\nVERSION:3.0\r\nN:Doe;John;;;\r\nFN:John Doe\r\nORG:Acme Corp\r\nTITLE:CEO\r\nEMAIL;TYPE=INTERNET:john@example.com\r\nTEL;TYPE=CELL:+1-555-0123\r\nEND:VCARD\r\n",
                  "file_name": "John_Doe.vcf"
                }
              }
            }
          },
          "400": {
            "description": "Bad request - missing required field, invalid email, or field too long",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "missing_first_name": {
                    "value": { "error": "Missing required field: first_name" }
                  },
                  "missing_last_name": {
                    "value": { "error": "Missing required field: last_name" }
                  },
                  "invalid_email": {
                    "value": { "error": "Invalid email format" }
                  },
                  "field_too_long": {
                    "value": { "error": "Field 'first_name' exceeds maximum length of 500 characters" }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (2 requests per second per IP)",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "example": "Retry later\n"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying",
                "schema": {
                  "type": "integer",
                  "example": 1
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SizeCheckResult": {
        "type": "object",
        "properties": {
          "file_name": {
            "type": "string",
            "description": "Original filename of the uploaded image"
          },
          "file_size_bytes": {
            "type": "integer",
            "description": "File size in bytes"
          },
          "width_px": {
            "type": "integer",
            "description": "Image width in pixels (larger dimension)"
          },
          "height_px": {
            "type": "integer",
            "description": "Image height in pixels (smaller dimension)"
          },
          "aspect_ratio": {
            "type": "number",
            "description": "Width-to-height ratio"
          },
          "standards": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StandardCheck"
            }
          },
          "print_quality": {
            "$ref": "#/components/schemas/PrintQuality"
          }
        }
      },
      "StandardCheck": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Standard name",
            "enum": ["US Standard", "EU / ISO 7810", "Japanese"]
          },
          "dimensions": {
            "type": "string",
            "description": "Human-readable dimensions"
          },
          "aspect_ratio_match": {
            "type": "boolean",
            "description": "Whether the image matches this standard's aspect ratio (2% tolerance)"
          },
          "estimated_dpi": {
            "type": "integer",
            "description": "Estimated DPI if printed at this standard's size"
          },
          "status": {
            "type": "string",
            "description": "Overall compatibility status",
            "enum": ["perfect_match", "correct_ratio_low_dpi", "correct_ratio_too_low_res", "aspect_ratio_mismatch"]
          }
        }
      },
      "PrintQuality": {
        "type": "object",
        "properties": {
          "estimated_dpi": {
            "type": "integer",
            "description": "Estimated DPI based on US standard width (3.5 inches)"
          },
          "print_ready": {
            "type": "boolean",
            "description": "true if >= 300 DPI"
          },
          "high_quality": {
            "type": "boolean",
            "description": "true if >= 600 DPI"
          },
          "minimum_usable": {
            "type": "boolean",
            "description": "true if >= 150 DPI"
          }
        }
      },
      "VcardGenerateRequest": {
        "type": "object",
        "required": ["first_name", "last_name"],
        "properties": {
          "first_name": {
            "type": "string",
            "description": "Contact's first name",
            "maxLength": 500
          },
          "last_name": {
            "type": "string",
            "description": "Contact's last name",
            "maxLength": 500
          },
          "email": {
            "type": "string",
            "format": "email",
            "description": "Email address",
            "maxLength": 500
          },
          "phone": {
            "type": "string",
            "description": "Phone number",
            "maxLength": 500
          },
          "company": {
            "type": "string",
            "description": "Company or organization name",
            "maxLength": 500
          },
          "title": {
            "type": "string",
            "description": "Job title",
            "maxLength": 500
          },
          "website": {
            "type": "string",
            "format": "uri",
            "description": "Website URL",
            "maxLength": 500
          },
          "address": {
            "type": "string",
            "description": "Physical address",
            "maxLength": 500
          },
          "linkedin_url": {
            "type": "string",
            "format": "uri",
            "description": "LinkedIn profile URL",
            "maxLength": 500
          },
          "twitter_url": {
            "type": "string",
            "format": "uri",
            "description": "X / Twitter profile URL",
            "maxLength": 500
          }
        }
      },
      "VcardGenerateResult": {
        "type": "object",
        "properties": {
          "vcard": {
            "type": "string",
            "description": "Complete vCard 3.0 string ready to save as a .vcf file"
          },
          "file_name": {
            "type": "string",
            "description": "Suggested filename (e.g. John_Doe.vcf)"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        }
      }
    }
  }
}
