openapi: 3.2.0 info: contact: email: support@aiapplyd.com name: AI Applyd url: https://aiapplyd.com description: 'The AI Applyd API runs the whole job hunt for you: it matches you to roles that fit your profile, rewrites your resume for each posting, writes the cover letter the form asks for, and auto-applies across the major applicant tracking systems.' license: name: Proprietary url: https://aiapplyd.com/legal/terms title: AI Applyd Public Ats Score API version: 115c47ce servers: - description: Current environment url: https://api.aiapplyd.com/api/v1 security: - BearerAuth: [] tags: - name: public-ats-score paths: /public/ats-score: post: tags: - public-ats-score summary: Anonymous ATS score (pre-auth lead magnet, paste text) description: Returns a top-line ATS compatibility score (0-100) plus the top 3 matching and missing keywords for an unauthenticated visitor. Uses ONLY free-tier OpenRouter models. Rate-limited 10/hour per IP. The full gap analysis, rewrite suggestions, and keyword strategy are intentionally NOT returned here - they remain behind the email-gate / signup wall. requestBody: content: application/json: schema: $ref: '#/components/schemas/AnonymousAtsScoreRequest' responses: '200': description: Top-line ATS score with limited keyword preview content: application/json: schema: $ref: '#/components/schemas/AnonymousAtsScoreResponse' '404': description: Not Found content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' operationId: postPublicAtsScore /public/ats-score/upload: post: tags: - public-ats-score summary: Anonymous ATS score (pre-auth lead magnet, upload) description: 'Same scoring contract as `/public/ats-score` but accepts a PDF or DOCX upload via multipart/form-data. Server-side text extraction then runs the same free-tier scoring core. Hard caps: 5 MB file, PDF or DOCX only.' requestBody: content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: Resume file (PDF or DOCX). Max 5 MB. Magic-byte validated server-side. jobDescription: type: string description: Optional job description text. When omitted the score is generic ATS compatibility only. required: - file responses: '200': description: Top-line ATS score with limited keyword preview content: application/json: schema: $ref: '#/components/schemas/AnonymousAtsScoreResponse' '404': description: Not Found content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' '500': description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/ApiErrorResponse' operationId: postPublicAtsScoreUpload components: schemas: AnonymousAtsScorePayload: type: object properties: matchingKeywords: type: array items: type: string maxItems: 3 description: Top 3 strongest keyword matches between the resume and JD. Empty array when no JD was provided. example: - TypeScript - React - Node.js missingKeywords: type: array items: type: string maxItems: 3 description: Top 3 most important JD keywords missing from the resume. Empty array when no JD was provided. example: - GraphQL - CI/CD - Kubernetes modelName: type: string description: Free-tier OpenRouter model that produced this score. Surfaced for transparency, not used by the client. example: nvidia/nemotron-3-nano-30b-a3b:free overallScore: type: integer minimum: 0 maximum: 100 description: Overall ATS compatibility score (0-100). example: 72 resumeHash: type: string description: SHA-256 prefix of the resume text. Used as an idempotency key for the per-resume rate limit. example: 3f4c7a8e1b2d5f6a required: - matchingKeywords - missingKeywords - modelName - overallScore - resumeHash additionalProperties: false ResponseMetadata: type: object properties: duration: type: number description: Request duration in milliseconds example: 150 exclusiveMinimum: 0 performance: type: object properties: dbQueries: type: integer minimum: 0 totalDbTime: type: number minimum: 0 description: Performance metrics (preview/local only) requestId: type: string description: Unique request identifier example: req_abc123 timestamp: type: string format: date-time description: ISO 8601 timestamp example: '2026-09-25T17:29:47.224Z' version: type: string description: API version example: v1 AnonymousAtsScoreResponse: type: object properties: data: $ref: '#/components/schemas/AnonymousAtsScorePayload' meta: $ref: '#/components/schemas/ResponseMetadata' success: type: boolean enum: - true required: - data - success additionalProperties: false description: Successful API response AnonymousAtsScoreRequest: type: object properties: jobDescription: type: string minLength: 50 maxLength: 30000 description: Optional job description text. When omitted the score is generic ATS compatibility only. example: We are looking for a senior backend engineer with 5+ years of TypeScript and PostgreSQL experience... resumeText: type: string minLength: 100 maxLength: 50000 description: Plain-text resume content. The web client extracts this from PDF/DOCX uploads via the bundled unpdf/docx parsers before calling this endpoint, OR sends pasted text directly. example: 'Jane Doe - Senior Software Engineer Experience - Built distributed systems at Acme Corp...' required: - resumeText additionalProperties: false ApiErrorResponse: type: object properties: error: type: object properties: code: type: string context: oneOf: - type: object properties: errorType: type: string enum: - validation field: type: string fieldErrors: type: array items: type: object properties: code: type: string expected: type: string field: type: string message: type: string received: type: string required: - field - message schemaName: type: string required: - errorType - type: object properties: attemptedEmail: type: string format: email errorType: type: string enum: - authentication failureReason: type: string enum: - invalid_credentials - account_locked - expired_token - token_expired - missing_token - invalid_token - session_expired description: Reason for authentication failure example: token_expired ipAddress: type: string operation: type: string service: type: string userAgent: type: string required: - errorType - type: object properties: actualPermission: type: string errorType: type: string enum: - authorization requiredPermission: type: string resource: type: string resourceId: type: string userId: type: string required: - errorType - type: object properties: constraint: type: string errorType: type: string enum: - database operation: type: string enum: - insert - update - delete - select - batch - transaction - migration description: Type of database operation example: select resourceId: type: string sqlState: type: string table: type: string userId: type: string required: - errorType - type: object properties: endpoint: type: string errorType: type: string enum: - external_service httpStatus: type: number operation: type: string resourceId: type: string responseTime: type: number retryAttempt: type: integer service: type: string serviceName: type: string userId: type: string required: - errorType - type: object properties: errorType: type: string enum: - resource resource: type: string resourceId: type: string service: type: string userId: type: string required: - errorType - type: object properties: errorType: type: string enum: - rate_limit limit: type: number resetTime: type: string windowMs: type: number required: - errorType - type: object properties: configKey: type: string errorType: type: string enum: - configuration operation: type: string service: type: string required: - errorType description: Type-safe error context information example: errorType: validation fieldErrors: - field: email message: Invalid email format details: oneOf: - type: object properties: detailType: type: string enum: - validation validationErrors: type: array items: type: object properties: code: type: string field: type: string message: type: string required: - field - message required: - detailType - validationErrors additionalProperties: false - type: object properties: detailType: type: string enum: - service_error originalError: type: string serviceName: type: string required: - detailType - serviceName additionalProperties: false - type: object properties: currentSize: type: number detailType: type: string enum: - batch originalError: type: string statementCount: type: number required: - detailType additionalProperties: false - type: object properties: detailType: type: string enum: - rate_limit limit: type: number resetTime: type: string windowMs: type: number required: - detailType - limit - resetTime - windowMs additionalProperties: false - type: object properties: conflictingField: type: string detailType: type: string enum: - resource resourceId: anyOf: - type: string - type: number resourceType: type: string required: - detailType additionalProperties: false - type: object properties: detailType: type: string enum: - generic info: type: string required: - detailType additionalProperties: false - type: object properties: currentTokens: type: integer minimum: 0 detailType: type: string enum: - insufficient_tokens requiredTokens: type: integer minimum: 0 required: - currentTokens - detailType - requiredTokens additionalProperties: false message: type: string validation: type: array items: type: object properties: code: type: string field: type: string message: type: string required: - field - message additionalProperties: false required: - code - message additionalProperties: false meta: $ref: '#/components/schemas/ResponseMetadata' success: type: boolean enum: - false required: - error - success additionalProperties: false securitySchemes: BearerAuth: description: 'Session token from signing in to AI Applyd, sent as `Authorization: Bearer `.' scheme: bearer type: http