{"openapi":"3.1.0","info":{"title":"ProofTrace API","description":"\nProofTrace exposes a compact HTTP API for public-source identity review.\n\n## Core Integration Flow\n\n1. Submit a lookup with `POST /api/v1/checks`.\n2. Store the returned `jobId`.\n3. Poll `GET /api/v1/checks/{jobId}` until the status becomes `completed` or `failed`.\n4. When `links.archive` is present, download the ZIP report from `GET /api/v1/checks/{jobId}/archive`.\n\n## Input Model\n\nClients can submit either a simple `query` or a structured `inputs` object. Structured\ninputs are preferred for integrations because names, emails, phones, usernames and\nother known aliases stay typed while the backend still treats them as signals for the\nsame subject.\n\n## Consent And Use Limits\n\nEvery check request must include all consent flags set to `true`. ProofTrace is built\nfor permitted public-source review. It is not a consumer-reporting agency endpoint and\nmust not be used for employment, tenant, credit, insurance or other FCRA-style\neligibility decisions.\n\n## Authentication\n\nSearch creation is public in the current B2C flow. Personal-cabinet endpoints require\nthe authenticated user context header `X-ProofTrace-User-Id`; the legacy\n`X-CheckMe-User-Id` header is still accepted during migration. Login uses\n`POST /api/v1/auth/login` and returns the current cabinet profile.\n\n## Response Shape\n\nSuccess responses are typed JSON. Error responses use FastAPI's standard\n`{\"detail\": ...}` shape, with the global fallback returning\n`{\"detail\": \"Internal server error.\", \"code\": \"internal_error\"}`.\n","termsOfService":"https://prooftrace.org/terms-conditions","contact":{"name":"ProofTrace API","url":"https://prooftrace.org/docs"},"license":{"name":"Proprietary"},"version":"0.1.0"},"servers":[{"url":"https://prooftrace.org","description":"Production API and Swagger documentation."},{"url":"http://localhost","description":"Local gateway used for development and testing."}],"paths":{"/api/v1/health":{"get":{"tags":["System Health"],"summary":"Check API health","description":"Return service name, status and API version for deployment and load-balancer checks. This is a process-level liveness endpoint: it does not run a deep PostgreSQL, RabbitMQ or worker scan, so it is safe to call frequently.","operationId":"checkApiHealth","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/geo/country":{"get":{"tags":["System Health"],"summary":"Resolve client country","description":"Return the best available ISO-2 country signal for the current request. Reverse-proxy and CDN IP-country headers are preferred; `Accept-Language` is only a development fallback. The response is used by the landing page to preselect the phone country without hardcoding one market.","operationId":"resolveClientGeoCountry","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientGeoCountryResponse"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Authentication"],"summary":"Login to the personal cabinet","description":"Verify account credentials by username or email and return the full personal-cabinet profile. Failed logins are written to the ProofTrace authentication-failure log so fail2ban can ban repeated attackers by IP.","operationId":"loginPersonalCabinetAccount","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Credentials are valid. The response contains profile, balance, search history, transaction history and deletion lifecycle fields for the authenticated user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileResponse"}}}},"401":{"description":"The login or password is invalid.","content":{"application/json":{"example":{"detail":"Login or password is incorrect."}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/checks":{"post":{"tags":["Background Checks"],"summary":"Submit a background check request","description":"Create one asynchronous public-source trace job. The request can use a simple `query` or a structured `inputs` object with typed names, emails, phones, nicknames and aliases. ProofTrace stores a queued status record, publishes a RabbitMQ worker task and returns a `jobId` plus follow-up links. Poll `GET /api/v1/checks/{jobId}` until the job reaches `completed` or `failed`.","operationId":"submitBackgroundCheckRequest","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckCreateRequest"},"examples":{"generalLookup":{"summary":"General person lookup","description":"Submit a generic public-web background check request for a person or free-text query.","value":{"query":"Philip Pristupa","lookupType":"general","consent":{"acceptedTerms":true,"privacyAcknowledged":true,"fcraAcknowledged":true},"clientReference":"web-form-001","metadata":{"source":"landing-page","locale":"en-US"}}},"emailLookup":{"summary":"Email lookup","description":"Submit an email-focused lookup while still using the shared evidence pipeline.","value":{"query":"person@example.com","lookupType":"email","consent":{"acceptedTerms":true,"privacyAcknowledged":true,"fcraAcknowledged":true}}},"phoneLookup":{"summary":"Phone lookup","description":"Submit a phone-number background check request for the future B2C UI.","value":{"query":"+1 415 555 0100","lookupType":"phone","consent":{"acceptedTerms":true,"privacyAcknowledged":true,"fcraAcknowledged":true}}},"combinedLookup":{"summary":"Combined equivalent lookup","description":"Submit one primary query plus equivalent aliases such as alternate spellings, usernames or emails for the same person.","value":{"query":"Philip Pristupa","aliases":["philipgeneralmail@gmail.com","Пилип Приступа"],"lookupType":"person","consent":{"acceptedTerms":true,"privacyAcknowledged":true,"fcraAcknowledged":true},"metadata":{"source":"forensics-console","locale":"en-US"}}},"structuredCombinedLookup":{"summary":"Structured combined lookup","description":"Submit typed JSON inputs for the same person while the backend packs them into minimal seed searches.","value":{"inputs":{"names":["Philip Pristupa","Пилип Приступа"],"emails":["philipgeneralmail@gmail.com"],"phones":[],"nicknames":["philip-pristupa"],"addresses":["Kyiv, Ukraine"],"tax_numbers":["0000000000"]},"lookupType":"combined","consent":{"acceptedTerms":true,"privacyAcknowledged":true,"fcraAcknowledged":true},"metadata":{"source":"forensics-console","case":"authorized-self-test"}}}}}},"required":true},"responses":{"202":{"description":"Background check request accepted and queued.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckCreateResponse"}}}},"400":{"description":"Required consent flags were not all true.","content":{"application/json":{"examples":{"badRequest":{"summary":"Consent not accepted","value":{"detail":"acceptedTerms, privacyAcknowledged and fcraAcknowledged must all be true."}}}}}},"422":{"description":"Request validation failed.","content":{"application/json":{"examples":{"validationError":{"summary":"Validation error","value":{"detail":[{"type":"string_too_short","loc":["body","query"],"msg":"String should have at least 1 character","input":""}]}}}}}},"503":{"description":"Task could not be published to RabbitMQ.","content":{"application/json":{"example":{"detail":"Failed to publish task to RabbitMQ."}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}}}}},"/api/v1/account/profile":{"get":{"tags":["Account"],"summary":"Get current user's personal cabinet data","description":"Return the current authenticated user's cabinet payload. The caller must provide `X-ProofTrace-User-Id` after login/session resolution. The response contains profile identity, balance, saved search history, transaction history placeholders, payment method placeholders and delayed account-deletion state.","operationId":"getCurrentAccountProfile","parameters":[{"name":"X-ProofTrace-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized.","title":"X-Prooftrace-User-Id"},"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized."},{"name":"X-CheckMe-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true,"title":"X-Checkme-User-Id"},"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true}],"responses":{"200":{"description":"Current user's personal cabinet data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileResponse"}}}},"401":{"description":"Authentication is missing or invalid."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/search-history":{"delete":{"tags":["Account"],"summary":"Clear current user's search history","description":"Remove all saved search query history rows for the authenticated account user. Other users' history is not affected. The endpoint is idempotent from a client perspective: zero deleted rows still return a successful response with `deletedCount: 0`.","operationId":"clearCurrentUserSearchHistory","parameters":[{"name":"X-ProofTrace-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized.","title":"X-Prooftrace-User-Id"},"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized."},{"name":"X-CheckMe-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true,"title":"X-Checkme-User-Id"},"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true}],"responses":{"200":{"description":"Search history was cleared for the current user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchHistoryClearResponse"}}}},"401":{"description":"The request did not include a valid authenticated user.","content":{"application/json":{"example":{"detail":"Authentication required."}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/deletion-request":{"post":{"tags":["Account"],"summary":"Request current account deletion","description":"Mark the authenticated account as pending deletion and schedule the final deletion timestamp 30 days after the request. This endpoint does not physically delete the account or related data. The delay keeps the account restorable through the restore endpoint until the scheduled deadline passes.","operationId":"requestCurrentAccountDeletion","parameters":[{"name":"X-ProofTrace-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized.","title":"X-Prooftrace-User-Id"},"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized."},{"name":"X-CheckMe-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true,"title":"X-Checkme-User-Id"},"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true}],"responses":{"200":{"description":"Account deletion was requested for the current user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDeletionActionResponse"}}}},"401":{"description":"The request did not include a valid authenticated user.","content":{"application/json":{"example":{"detail":"Authentication required."}}}},"409":{"description":"The account is already pending deletion.","content":{"application/json":{"example":{"detail":"Account deletion is already pending."}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/account/deletion-request/restore":{"post":{"tags":["Account"],"summary":"Restore current account before deletion","description":"Clear the authenticated account's pending-deletion state before physical deletion. This endpoint does not recreate deleted data or change login/logout behavior. It only cancels an active delayed deletion request that is still inside the recovery window.","operationId":"restoreCurrentAccountDeletion","parameters":[{"name":"X-ProofTrace-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized.","title":"X-Prooftrace-User-Id"},"description":"Authenticated ProofTrace user id. Required for personal cabinet endpoints until session-cookie auth is finalized."},{"name":"X-CheckMe-User-Id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true,"title":"X-Checkme-User-Id"},"description":"Deprecated CheckMe-era authenticated user id header. Accepted only for migration compatibility.","deprecated":true}],"responses":{"200":{"description":"Account deletion was restored for the current user.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDeletionActionResponse"}}}},"401":{"description":"The request did not include a valid authenticated user.","content":{"application/json":{"example":{"detail":"Authentication required."}}}},"409":{"description":"The account is not pending deletion or can no longer be restored.","content":{"application/json":{"example":{"detail":"Account is not pending deletion."}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/checks/{jobId}":{"get":{"tags":["Background Checks"],"summary":"Get background check status","description":"Return the latest known status for a queued, processing, completed or failed public-source trace job. The payload includes progress percent, worker phase, current stage metadata, final result summary when available, error message when failed and links for docs, self polling and archive download.","operationId":"getBackgroundCheckStatus","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","title":"Jobid"}}],"responses":{"200":{"description":"Current background check status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckStatusResponse"},"examples":{"queued":{"summary":"Queued job","value":{"jobId":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","status":"queued","query":"Philip Pristupa","lookupType":"general","createdAt":"2026-04-07T10:15:30.123456Z","updatedAt":"2026-04-07T10:15:30.123456Z","progress":{"percent":0,"phase":"queued","message":"Job accepted and waiting for a worker."},"links":{"self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","docs":"/docs"}}},"processing":{"summary":"Processing job","value":{"jobId":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","status":"processing","query":"Philip Pristupa","lookupType":"person","createdAt":"2026-04-07T10:15:30.123456Z","updatedAt":"2026-04-07T10:18:40.000000Z","progress":{"percent":34,"phase":"aggregating","message":"Aggregating stage evidence into one result set.","stageCurrent":2,"stageTotal":3,"stageQuery":"\"Philip Pristupa\" OR \"philipgeneralmail@gmail.com\"","pivotType":"seed","completedStages":1},"links":{"self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","docs":"/docs"}}},"completed":{"summary":"Completed job","value":{"jobId":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","status":"completed","query":"Philip Pristupa","lookupType":"general","createdAt":"2026-04-07T10:15:30.123456Z","updatedAt":"2026-04-07T10:22:10.654321Z","progress":{"percent":100,"phase":"completed","message":"Scan completed and results are ready.","completedStages":3},"result":{"query":"Philip Pristupa","total_found":100,"downloaded":87,"failed":13,"zip_path":"C:\\shared\\external_storage\\2026_04_07__10_22_10__1__vm-worker-1__Philip_Pristupa.zip","job_id":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","lookup_type":"general"},"links":{"self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","docs":"/docs"}}}}}}},"404":{"description":"The requested background check job was not found.","content":{"application/json":{"example":{"detail":"Check job not found."}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/checks/{jobId}/archive":{"get":{"tags":["Background Checks"],"summary":"Download background check archive","description":"Download the completed ZIP archive produced by a local or VM worker. Call this only after the status endpoint returns an archive link. The ZIP contains generated report artifacts and saved evidence files for the completed public-source trace.","operationId":"downloadBackgroundCheckArchive","parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string","title":"Jobid"}}],"responses":{"200":{"description":"ZIP archive for the completed check job.","content":{"application/json":{"schema":{}},"application/zip":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"The job or its completed ZIP archive was not found.","content":{"application/json":{"examples":{"jobMissing":{"summary":"Job not found","value":{"detail":"Check job not found."}},"archiveMissing":{"summary":"Archive not ready or missing","value":{"detail":"Check archive was not found."}}}}}},"500":{"description":"Unexpected internal error.","content":{"application/json":{"examples":{"internalError":{"summary":"Unexpected internal error","value":{"detail":"Internal server error.","code":"internal_error"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/local/controls/stop-all-checks":{"post":{"summary":"Stopallchecks","operationId":"stopAllChecks_local_controls_stop_all_checks_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/{path}":{"options":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Routelocalhost","operationId":"routeLocalHost__path__options","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AccountDeletionActionResponse":{"properties":{"isDeletionPending":{"type":"boolean","title":"Isdeletionpending","description":"Whether the account remains pending deletion after the action."},"deletionRequestedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletionrequestedat","description":"UTC timestamp when deletion was requested, if still pending."},"scheduledDeletionAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduleddeletionat","description":"UTC timestamp when physical deletion may happen, if still pending."},"message":{"type":"string","title":"Message","description":"Human-readable deletion lifecycle result message."}},"type":"object","required":["isDeletionPending","message"],"title":"AccountDeletionActionResponse","example":{"deletionRequestedAt":"2026-05-21T14:00:00Z","isDeletionPending":true,"message":"Account deletion requested.","scheduledDeletionAt":"2026-06-20T14:00:00Z"}},"AccountProfileResponse":{"properties":{"id":{"type":"integer","title":"Id","description":"Current account id. Mirrors userId during the current account model."},"userId":{"type":"integer","title":"Userid","description":"Authenticated user id used by account endpoints."},"login":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Login","description":"Login identifier used for the current session when returned by login."},"displayName":{"type":"string","title":"Displayname","description":"User-facing display name."},"email":{"type":"string","title":"Email","description":"Account email address."},"username":{"type":"string","title":"Username","description":"Account username."},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatarurl","description":"Optional avatar URL for the cabinet UI."},"balance":{"type":"string","title":"Balance","description":"Current account balance formatted as a decimal string."},"balanceCurrency":{"type":"string","title":"Balancecurrency","description":"ISO currency code for the account balance."},"isDeletionPending":{"type":"boolean","title":"Isdeletionpending","description":"Whether the account is inside the delayed deletion window."},"deletionRequestedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Deletionrequestedat","description":"UTC timestamp when deletion was requested, if pending."},"scheduledDeletionAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduleddeletionat","description":"UTC timestamp when physical deletion may happen, if pending."},"searchHistory":{"items":{"$ref":"#/components/schemas/AccountSearchHistoryItem"},"type":"array","title":"Searchhistory","description":"Most recent saved search queries for the authenticated user."},"transactionHistory":{"items":{"$ref":"#/components/schemas/AccountTransactionHistoryItem"},"type":"array","title":"Transactionhistory","description":"Balance transaction history rows for the authenticated user."},"paymentMethods":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Paymentmethods","description":"Saved payment method placeholders reserved for billing integration."}},"type":"object","required":["id","userId","displayName","email","username","balance","balanceCurrency","isDeletionPending"],"title":"AccountProfileResponse","example":{"balance":"0.00","balanceCurrency":"USD","displayName":"test-user","email":"test.user@example.com","id":1,"isDeletionPending":false,"login":"1111","paymentMethods":[],"searchHistory":[],"transactionHistory":[],"userId":1,"username":"test-user"}},"AccountSearchHistoryItem":{"properties":{"id":{"type":"integer","title":"Id","description":"Database id of the saved search-history row."},"queryText":{"type":"string","title":"Querytext","description":"Search query text saved for the authenticated user."},"createdAt":{"type":"string","format":"date-time","title":"Createdat","description":"UTC timestamp when this search-history row was created."}},"type":"object","required":["id","queryText","createdAt"],"title":"AccountSearchHistoryItem"},"AccountTransactionHistoryItem":{"properties":{"id":{"type":"integer","title":"Id","description":"Database id of the balance transaction row."},"transactionType":{"type":"string","title":"Transactiontype","description":"Ledger direction or action type such as top_up or deduction."},"amount":{"type":"string","title":"Amount","description":"Decimal amount formatted as a string to preserve money precision."},"status":{"type":"string","title":"Status","description":"Transaction status such as pending, completed or failed."},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Human-readable transaction note shown in the cabinet."},"paymentMethod":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paymentmethod","description":"Payment method label when available."},"externalPaymentProvider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalpaymentprovider","description":"External processor name when a payment provider is attached."},"externalPaymentId":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Externalpaymentid","description":"External processor transaction id when available."},"balanceAfterTransaction":{"type":"string","title":"Balanceaftertransaction","description":"Account balance after the transaction, formatted as a decimal string."},"createdAt":{"type":"string","format":"date-time","title":"Createdat","description":"UTC timestamp when the transaction row was created."}},"type":"object","required":["id","transactionType","amount","status","balanceAfterTransaction","createdAt"],"title":"AccountTransactionHistoryItem"},"CheckCreateRequest":{"properties":{"query":{"anyOf":[{"type":"string","maxLength":512,"minLength":1},{"type":"null"}],"title":"Query","description":"Free-text lookup input such as a name, email, phone or username.","examples":["Philip Pristupa","person@example.com","+1 415 555 0100"]},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases","description":"Equivalent lookup inputs for the same entity, for example alternate spellings, usernames or emails.","examples":[["philipgeneralmail@gmail.com","Пилип Приступа"]]},"inputs":{"anyOf":[{"$ref":"#/components/schemas/StructuredLookupInputs"},{"type":"null"}],"description":"Typed JSON lookup inputs for one subject. Values are treated as equivalent and packed into minimal seed searches."},"lookupType":{"type":"string","enum":["combined","general","person","name","phone","email","address","tax_number","itn","nickname","username"],"title":"Lookuptype","description":"Caller intent for the lookup. v1 maps every supported type to the shared evidence pipeline.","default":"general","examples":["general","email","phone"]},"consent":{"$ref":"#/components/schemas/ConsentInput"},"clientReference":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Clientreference","description":"Optional client-side correlation id, for example a form submission id.","examples":["web-form-001"]},"callbackUrl":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Callbackurl","description":"Reserved for future async webhook notification support.","examples":["https://client.example.com/prooftrace/callback"]},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata","description":"Free-form client metadata preserved with the queued job.","examples":[{"locale":"en-US","source":"landing-page"}]}},"type":"object","required":["consent"],"title":"CheckCreateRequest","example":{"clientReference":"web-form-001","consent":{"acceptedTerms":true,"fcraAcknowledged":true,"privacyAcknowledged":true},"lookupType":"general","metadata":{"locale":"en-US","source":"landing-page"},"query":"Philip Pristupa"}},"CheckCreateResponse":{"properties":{"jobId":{"type":"string","title":"Jobid","description":"Stable UUID assigned to the queued check job."},"status":{"type":"string","enum":["queued","processing","completed","failed"],"title":"Status","description":"Initial lifecycle state. Accepted jobs return queued."},"query":{"type":"string","title":"Query","description":"Normalized primary query that was queued for processing."},"lookupType":{"type":"string","enum":["combined","general","person","name","phone","email","address","tax_number","itn","nickname","username"],"title":"Lookuptype","description":"Lookup intent accepted for this job."},"createdAt":{"type":"string","title":"Createdat","description":"UTC ISO timestamp when the job status record was created."},"links":{"$ref":"#/components/schemas/LinkSet","description":"Follow-up links for polling, documentation and archive download."}},"type":"object","required":["jobId","status","query","lookupType","createdAt","links"],"title":"CheckCreateResponse","example":{"createdAt":"2026-04-07T10:15:30.123456Z","jobId":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","links":{"docs":"/docs","self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc"},"lookupType":"general","query":"Philip Pristupa","status":"queued"}},"CheckStatusResponse":{"properties":{"jobId":{"type":"string","title":"Jobid","description":"Stable UUID of the check job being polled."},"status":{"type":"string","title":"Status","description":"Current lifecycle state such as queued, processing, completed or failed."},"query":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Query","description":"Primary query stored for this job."},"lookupType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lookuptype","description":"Lookup intent stored for this job."},"createdAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Createdat","description":"UTC ISO timestamp when the job was created."},"updatedAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updatedat","description":"UTC ISO timestamp for the latest status update."},"progress":{"anyOf":[{"$ref":"#/components/schemas/JobProgress"},{"type":"null"}],"description":"Structured worker progress while the job is queued or processing."},"result":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Result","description":"Final worker result summary when the job completes."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Failure message when the job status is failed."},"links":{"$ref":"#/components/schemas/LinkSet","description":"Follow-up links for this job, including archive when available."}},"type":"object","required":["jobId","status","links"],"title":"CheckStatusResponse","example":{"createdAt":"2026-04-07T10:15:30.123456Z","jobId":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","links":{"docs":"/docs","self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc"},"lookupType":"general","progress":{"completedStages":3,"message":"Scan completed and results are ready.","percent":100,"phase":"completed"},"query":"Philip Pristupa","result":{"downloaded":87,"failed":13,"job_id":"b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc","lookup_type":"general","query":"Philip Pristupa","total_found":100,"zip_path":"C:\\shared\\external_storage\\2026_04_07__10_22_10__1__vm-worker-1__Philip_Pristupa.zip"},"status":"completed","updatedAt":"2026-04-07T10:22:10.654321Z"}},"ClientGeoCountryResponse":{"properties":{"countryIso":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Countryiso","description":"ISO-3166 alpha-2 country code when one can be inferred."},"source":{"type":"string","title":"Source","description":"Signal used to infer the country, or unavailable.","default":"unavailable"}},"type":"object","title":"ClientGeoCountryResponse","example":{"countryIso":"US","source":"cf-ipcountry"}},"ConsentInput":{"properties":{"acceptedTerms":{"type":"boolean","title":"Acceptedterms","description":"Caller accepted ProofTrace terms for this lookup."},"privacyAcknowledged":{"type":"boolean","title":"Privacyacknowledged","description":"Caller acknowledged privacy and data-use limitations."},"fcraAcknowledged":{"type":"boolean","title":"Fcraacknowledged","description":"Caller acknowledged ProofTrace is not for FCRA eligibility decisions."}},"type":"object","required":["acceptedTerms","privacyAcknowledged","fcraAcknowledged"],"title":"ConsentInput","example":{"acceptedTerms":true,"fcraAcknowledged":true,"privacyAcknowledged":true}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"service":{"type":"string","title":"Service","description":"Configured API service name."},"status":{"type":"string","title":"Status","description":"Health status. `ok` means the API process answered."},"version":{"type":"string","title":"Version","description":"Configured API version string."}},"type":"object","required":["service","status","version"],"title":"HealthResponse","example":{"service":"ProofTrace API","status":"ok","version":"0.1.0"}},"JobProgress":{"properties":{"percent":{"type":"integer","title":"Percent","description":"Approximate 0..100 completion percentage for the current job."},"phase":{"type":"string","title":"Phase","description":"Short machine-readable phase name such as queued, scanning or archiving."},"message":{"type":"string","title":"Message","description":"Human-readable progress message for the operator UI."},"stageCurrent":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stagecurrent","description":"1-based current scan stage number when the worker is inside stage execution."},"stageTotal":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Stagetotal","description":"Current known number of planned stages, bounded by the worker stage limit."},"stageQuery":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stagequery","description":"Current query string being scanned or processed."},"pivotType":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pivottype","description":"Current pivot type such as seed, nickname, email or phone."},"completedStages":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Completedstages","description":"How many scan stages have already completed."}},"type":"object","required":["percent","phase","message"],"title":"JobProgress","example":{"completedStages":1,"message":"Aggregating stage evidence into one result set.","percent":34,"phase":"aggregating","pivotType":"seed","stageCurrent":2,"stageQuery":"\"Philip Pristupa\" OR \"philipgeneralmail@gmail.com\"","stageTotal":3}},"LinkSet":{"properties":{"self":{"type":"string","title":"Self","description":"Canonical API URL for the current resource."},"docs":{"type":"string","title":"Docs","description":"Swagger documentation URL for the current deployment.","default":"/docs"},"archive":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Archive","description":"ZIP archive download URL when a completed job has an archive."}},"type":"object","required":["self"],"title":"LinkSet","example":{"docs":"/docs","self":"/api/v1/checks/b62d4c51-08f8-4a8b-9d91-f8d99d28f3bc"}},"LoginRequest":{"properties":{"login":{"type":"string","maxLength":320,"minLength":1,"title":"Login","description":"Account email or username."},"password":{"type":"string","maxLength":1024,"minLength":1,"title":"Password","description":"Account password."}},"type":"object","required":["login","password"],"title":"LoginRequest","example":{"login":"Philip","password":"********"}},"SearchHistoryClearResponse":{"properties":{"deletedCount":{"type":"integer","minimum":0.0,"title":"Deletedcount","description":"Number of search history rows removed for the current user."},"message":{"type":"string","title":"Message","description":"Human-readable action result message."}},"type":"object","required":["deletedCount","message"],"title":"SearchHistoryClearResponse","example":{"deletedCount":2,"message":"Search history cleared."}},"StructuredLookupInputs":{"properties":{"names":{"items":{"type":"string"},"type":"array","title":"Names","description":"Known names or alternate spellings for the same subject.","examples":[["Philip Pristupa","Пилип Приступа"]]},"emails":{"items":{"type":"string"},"type":"array","title":"Emails","description":"Known email addresses for the same subject.","examples":[["philipgeneralmail@gmail.com"]]},"phones":{"items":{"type":"string"},"type":"array","title":"Phones","description":"Known phone numbers for the same subject.","examples":[["+1 415 555 0100"]]},"nicknames":{"items":{"type":"string"},"type":"array","title":"Nicknames","description":"Known usernames, handles or nicknames for the same subject.","examples":[["philip-pristupa"]]},"addresses":{"items":{"type":"string"},"type":"array","title":"Addresses","description":"Known addresses or location anchors for the same subject.","examples":[["Kyiv, Ukraine"]]},"tax_numbers":{"items":{"type":"string"},"type":"array","title":"Tax Numbers","description":"Known individual tax numbers or ITN values for the same subject.","examples":[["0000000000"]]},"aliases":{"items":{"type":"string"},"type":"array","title":"Aliases","description":"Other equivalent free-text aliases for the same subject."},"others":{"items":{"type":"string"},"type":"array","title":"Others","description":"Other high-confidence identifiers that do not fit the typed fields."}},"type":"object","title":"StructuredLookupInputs"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"System Health","description":"Operational endpoints used by the landing page, deployment checks and integrations. These endpoints are intentionally lightweight: they expose API liveness and request-local country inference, not full worker or database diagnostics."},{"name":"Background Checks","description":"The asynchronous public-source trace flow. Create a check job, poll progress by `jobId`, then download the ZIP archive when the worker marks the job completed and exposes an archive link."},{"name":"Authentication","description":"Credential-based entry into the personal cabinet. Login returns the same account profile shape used by authenticated account endpoints."},{"name":"Account","description":"Authenticated personal-cabinet operations for profile refresh, search-history cleanup and delayed account deletion lifecycle. Current authentication is passed through `X-ProofTrace-User-Id`."}]}