mirror of
https://github.com/PrivateCaptcha/PrivateCaptcha.git
synced 2026-02-08 23:09:11 -06:00
749 lines
21 KiB
YAML
749 lines
21 KiB
YAML
openapi: 3.0.4
|
|
info:
|
|
title: Private Captcha - OpenAPI 3.0
|
|
description: |-
|
|
Private Captcha is an independent, privacy-first, self-hostable Proof-of-Work CAPTCHA service made in EU.
|
|
Instead of asking users to solve complex puzzles or track their behavior, Private Captcha solves an invisible cryptographic task in the background. The system automatically adjusts the task difficulty, ensuring smooth access for real users while making it too costly for bots to attempt. Cryptographic task provides equal security regardless of bot's intelligence level, making it effective even as AI technology improves.
|
|
|
|
Some useful links:
|
|
- [Private Captcha repository](https://github.com/PrivateCaptcha/PrivateCaptcha)
|
|
- [Official Documentation](https://docs.privatecaptcha.com)
|
|
termsOfService: https://privatecaptcha.com/legal/terms-and-conditions/
|
|
contact:
|
|
email: hello@privatecaptcha.com
|
|
license:
|
|
name: PolyForm Noncommercial License 1.0.0
|
|
url: https://polyformproject.org/licenses/noncommercial/1.0.0
|
|
version: 1.0.0
|
|
externalDocs:
|
|
description: Find out more about Private Captcha
|
|
url: https://privatecaptcha.com
|
|
servers:
|
|
- url: https://api.privatecaptcha.com
|
|
- url: https://api.eu.privatecaptcha.com
|
|
tags:
|
|
- name: puzzle
|
|
description: Fetch Puzzle for client widget
|
|
- name: verify
|
|
description: Verify puzzle solutions
|
|
externalDocs:
|
|
description: Find out more about Verify API
|
|
url: https://docs.privatecaptcha.com/docs/reference/verify-api/
|
|
- name: org
|
|
description: Organization management
|
|
- name: properties
|
|
description: Property management
|
|
- name: task
|
|
description: Async task management
|
|
paths:
|
|
/puzzle:
|
|
get:
|
|
tags:
|
|
- puzzle
|
|
summary: Retrieve a new puzzle
|
|
description: Returns a unique serialized signed puzzle for the widget
|
|
operationId: get-puzzle
|
|
parameters:
|
|
- name: sitekey
|
|
in: query
|
|
description: Property id for which the puzzle is requested
|
|
required: true
|
|
schema:
|
|
type: string
|
|
example: "aaaaaaaabbbbccccddddeeeeeeeeeeee"
|
|
- name: Origin
|
|
in: header
|
|
description: Domain that corresponds to the Property sitekey
|
|
schema:
|
|
type: string
|
|
example: "example.com"
|
|
responses:
|
|
"200":
|
|
description: Puzzle created
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
example: "Aaqqqqq7u8zM3d3u7u7u7u4AAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAA=.AQCiRYnFLBXoqfEYUz7Up+ktTXhxXgw="
|
|
headers:
|
|
X-Rate-Limit:
|
|
description: calls per second allowed to the user
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Remaining:
|
|
description: number of operations remaining in the given time slot
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Reset:
|
|
description: number of seconds until rate limit is reset
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
Retry-After:
|
|
description: recommended number of seconds to wait until retrying
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
"400":
|
|
description: Invalid sitekey value or Origin header is missing
|
|
"403":
|
|
description: Sitekey does not exist, Origin does not correspond to property
|
|
"429":
|
|
description: Rate limited
|
|
"500":
|
|
description: Unexpected internal error
|
|
/verify:
|
|
post:
|
|
tags:
|
|
- verify
|
|
summary: Verify puzzle solution (official API)
|
|
description: API to verify form field with client solution used by SDKs and API clients
|
|
operationId: post-verify
|
|
parameters:
|
|
- name: X-PC-Sitekey
|
|
in: header
|
|
description: "(optional) Sitekey of the property to ensure the solution is for"
|
|
required: false
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
description: Solution
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
required: true
|
|
responses:
|
|
"200":
|
|
description: Successful operation
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/VerifyResponse"
|
|
headers:
|
|
X-Rate-Limit:
|
|
description: calls per second allowed to the API key
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Remaining:
|
|
description: number of operations remaining in the given time slot
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Reset:
|
|
description: number of seconds until rate limit is reset
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
Retry-After:
|
|
description: recommended number of seconds to wait until retrying
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
"400":
|
|
description: Invalid API key format
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/siteverify:
|
|
post:
|
|
tags:
|
|
- verify
|
|
summary: Verify puzzle solution (reCAPCHA-compatible)
|
|
description: reCAPCHA-compatible API to verify form field with client solution
|
|
operationId: post-siteverify
|
|
requestBody:
|
|
content:
|
|
application/x-www-form-urlencoded:
|
|
schema:
|
|
type: object
|
|
required:
|
|
- secret
|
|
- response
|
|
properties:
|
|
secret:
|
|
description: API key (auth)
|
|
type: string
|
|
response:
|
|
description: Solution of the solved captcha
|
|
type: string
|
|
sitekey:
|
|
description: (optional) Sitekey of the property to ensure the solution is for
|
|
type: string
|
|
required: true
|
|
responses:
|
|
"200":
|
|
description: Successful operation
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SiteVerifyResponse"
|
|
headers:
|
|
X-Rate-Limit:
|
|
description: calls per second allowed to the API key
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Remaining:
|
|
description: number of operations remaining in the given time slot
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
X-RateLimit-Reset:
|
|
description: number of seconds until rate limit is reset
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
Retry-After:
|
|
description: recommended number of seconds to wait until retrying
|
|
schema:
|
|
type: integer
|
|
format: int32
|
|
"400":
|
|
description: Invalid API key format
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
/asynctask/{id}:
|
|
get:
|
|
tags:
|
|
- task
|
|
summary: Get async task status
|
|
operationId: get-async-task
|
|
parameters:
|
|
- name: id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Task status
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/AsyncTaskResultOutput"
|
|
"403":
|
|
description: API key not valid or user does does not have right to access this async task
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/orgs:
|
|
get:
|
|
tags:
|
|
- org
|
|
summary: Get user organizations
|
|
operationId: get-user-orgs
|
|
responses:
|
|
"200":
|
|
description: List of organizations
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/OrgOutput"
|
|
"400":
|
|
description: Invalid API key format
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/org:
|
|
post:
|
|
tags:
|
|
- org
|
|
summary: Create new organization
|
|
operationId: create-org
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OrgInput"
|
|
responses:
|
|
"200":
|
|
description: Organization created
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/OrgOutput"
|
|
"400":
|
|
description: Invalid API key format
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
put:
|
|
tags:
|
|
- org
|
|
summary: Update organization
|
|
operationId: update-org
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OrgInput"
|
|
responses:
|
|
"200":
|
|
description: Organization updated
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/OrgOutput"
|
|
"400":
|
|
description: Invalid API key format or invalid organization ID
|
|
"403":
|
|
description: API key not found or user is not organization owner
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
delete:
|
|
tags:
|
|
- org
|
|
summary: Delete organization
|
|
operationId: delete-org
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OrgInput"
|
|
responses:
|
|
"200":
|
|
description: Organization deleted
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/APIResponse"
|
|
"400":
|
|
description: Invalid API key format or invalid organization ID
|
|
"403":
|
|
description: API key not found or user is not organization owner
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/org/{org_id}/properties:
|
|
get:
|
|
tags:
|
|
- properties
|
|
summary: Get organization properties
|
|
operationId: get-org-properties
|
|
parameters:
|
|
- name: org_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: page
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
- name: per_page
|
|
in: query
|
|
schema:
|
|
type: integer
|
|
responses:
|
|
"200":
|
|
description: List of properties
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/OrgPropertyOutput"
|
|
"400":
|
|
description: Invalid API key format or invalid organization ID
|
|
"403":
|
|
description: API key not found or user is not a member or owner of organization
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
post:
|
|
tags:
|
|
- properties
|
|
summary: Create properties
|
|
operationId: create-properties
|
|
parameters:
|
|
- name: org_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/CreatePropertyInput"
|
|
responses:
|
|
"200":
|
|
description: Creation task started
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/AsyncTaskOutput"
|
|
"400":
|
|
description: Invalid API key format or invalid organization ID
|
|
"403":
|
|
description: API key not found or user is not an owner of organization
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/properties:
|
|
delete:
|
|
tags:
|
|
- properties
|
|
summary: Delete properties
|
|
operationId: delete-properties
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Deletion task started
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/AsyncTaskOutput"
|
|
"400":
|
|
description: Invalid API key format or invalid body payload
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
put:
|
|
tags:
|
|
- properties
|
|
summary: Update properties
|
|
operationId: update-properties
|
|
requestBody:
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/UpdatePropertyInput"
|
|
responses:
|
|
"200":
|
|
description: Update task started
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/AsyncTaskOutput"
|
|
"400":
|
|
description: Invalid API key format or invalid body payload
|
|
"403":
|
|
description: API key not found
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
/org/{org_id}/property/{property_id}:
|
|
get:
|
|
tags:
|
|
- properties
|
|
summary: Get property details
|
|
operationId: get-property
|
|
parameters:
|
|
- name: org_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: property_id
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Property details
|
|
content:
|
|
application/json:
|
|
schema:
|
|
allOf:
|
|
- $ref: "#/components/schemas/APIResponse"
|
|
- type: object
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/PropertyOutput"
|
|
"400":
|
|
description: Invalid API key format, organization or property IDs
|
|
"403":
|
|
description: API key not found or user does not have access to this property in this organization
|
|
"429":
|
|
description: API key rate limited
|
|
security:
|
|
- ApiKeyAuth: []
|
|
|
|
components:
|
|
schemas:
|
|
SiteVerifyResponse:
|
|
type: object
|
|
required:
|
|
- success
|
|
- error-codes
|
|
- challenge_ts
|
|
- hostname
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
error-codes:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/VerifyErrorCode"
|
|
hostname:
|
|
type: string
|
|
example: example.com
|
|
challenge_ts:
|
|
type: string
|
|
format: date-time
|
|
example: "2009-11-10T23:00:00Z"
|
|
score:
|
|
type: number
|
|
action:
|
|
type: string
|
|
VerifyErrorCode:
|
|
type: string
|
|
enum:
|
|
- no-error
|
|
- error-other
|
|
- solution-duplicates
|
|
- solution-invalid
|
|
- solution-bad-format
|
|
- puzzle-expired
|
|
- property-invalid
|
|
- property-owner-mismatch
|
|
- solution-verified-before
|
|
- property-test
|
|
- maintenance-mode
|
|
- integrity-error
|
|
- org-scope-error
|
|
VerifyResponse:
|
|
type: object
|
|
required:
|
|
- success
|
|
- code
|
|
- timestamp
|
|
- origin
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
code:
|
|
type: number
|
|
origin:
|
|
type: string
|
|
example: example.com
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
example: "2009-11-10T23:00:00Z"
|
|
APIResponse:
|
|
type: object
|
|
properties:
|
|
meta:
|
|
$ref: "#/components/schemas/ResponseMetadata"
|
|
data:
|
|
type: object
|
|
pagination:
|
|
$ref: "#/components/schemas/Pagination"
|
|
required:
|
|
- meta
|
|
- data
|
|
ResponseMetadata:
|
|
type: object
|
|
properties:
|
|
code:
|
|
type: integer
|
|
example: 1000
|
|
request_id:
|
|
type: string
|
|
example: 9m4e2mr0ui3e8a215n4g
|
|
description:
|
|
type: string
|
|
example: OK
|
|
Pagination:
|
|
type: object
|
|
properties:
|
|
page:
|
|
type: integer
|
|
example: 1
|
|
per_page:
|
|
type: integer
|
|
example: 50
|
|
has_more:
|
|
type: boolean
|
|
OrgInput:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: ueRWrHqlki
|
|
name:
|
|
type: string
|
|
example: "My Organization"
|
|
OrgOutput:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: XGfmWT7ZPI
|
|
name:
|
|
type: string
|
|
example: "My Organization"
|
|
PropertyGrowth:
|
|
type: string
|
|
enum:
|
|
- constant
|
|
- slow
|
|
- medium
|
|
- fast
|
|
PropertySettings:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
example: "Company Website"
|
|
level:
|
|
type: integer
|
|
example: 95
|
|
growth:
|
|
$ref: "#/components/schemas/PropertyGrowth"
|
|
validity_seconds:
|
|
type: integer
|
|
example: 21600
|
|
allow_subdomains:
|
|
type: boolean
|
|
allow_localhost:
|
|
type: boolean
|
|
max_replay_count:
|
|
type: integer
|
|
example: 1
|
|
CreatePropertyInput:
|
|
allOf:
|
|
- type: object
|
|
properties:
|
|
domain:
|
|
type: string
|
|
example: "example.com"
|
|
name:
|
|
type: string
|
|
example: "Company Website"
|
|
UpdatePropertyInput:
|
|
allOf:
|
|
- $ref: "#/components/schemas/PropertySettings"
|
|
- type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: t3hlMTu0XX
|
|
PropertyOutput:
|
|
allOf:
|
|
- $ref: "#/components/schemas/PropertySettings"
|
|
- type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: 0VgGggmbGa
|
|
domain:
|
|
type: string
|
|
example: example.com
|
|
sitekey:
|
|
type: string
|
|
example: 525e0ef5b9bc489f882274b3ca24b710
|
|
OrgPropertyOutput:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: vDWtASYqrB
|
|
name:
|
|
type: string
|
|
example: "Company Website"
|
|
sitekey:
|
|
type: string
|
|
example: 288a919fa0424bc09ed0d935fdc93433
|
|
AsyncTaskOutput:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: e3e6854e06944cf48f49f93abb5a527e
|
|
AsyncTaskResultOutput:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
example: e3e6854e06944cf48f49f93abb5a527e
|
|
finished:
|
|
type: boolean
|
|
result:
|
|
type: object
|
|
securitySchemes:
|
|
ApiKeyAuth:
|
|
type: apiKey
|
|
in: header
|
|
name: X-Api-Key
|