FairePlace Coupons API
Coupon validation and redemption (free-signature / discount codes).
Coupon validation and redemption (free-signature / discount codes).
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/faireplace-com:faireplace-com-coupons-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: FairePlace Property Management Coupons API
description: 'Comprehensive API for managing properties, leases, tenants, and all aspects of real estate management.
Built with Rust and Actix-web following hexagonal architecture principles.
## Authentication
This API uses API keys for authentication with tenant-based isolation.
## Base URL
- Production: `https://api.faireplace.com/api`'
version: 1.0.0
contact:
name: FairePlace API Support
email: api-support@faireplace.com
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.faireplace.com/api
description: Production server
security:
- BearerAuth: []
tags:
- name: Coupons
description: Coupon validation and redemption (free-signature / discount codes).
paths:
/coupons/validate:
post:
operationId: validateCoupon
summary: Validate a coupon
description: 'Previews a coupon **without consuming it**. Reports whether the coupon
can be redeemed by the current tenant.
## Behavior
- For `free_signature` coupons, `signatures_count` indicates how many
free signatures would be granted.
- For `discount` coupons, `discount_will_apply` is `true`: the discount
is applied directly at signature checkout (NOT via `/coupons/redeem`).
- `is_valid` is `true` only if the coupon is active, not expired, not
saturated, and not already redeemed by this tenant.
## Usage Example
```bash
curl -X POST https://api.faireplace.com/api/coupons/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d ''{ "code": "PROMO2024" }''
```
**Response**:
```json
{
"code": "PROMO2024",
"kind": "free_signature",
"description": "2 free signatures",
"signatures_count": 2,
"discount_will_apply": false,
"already_redeemed": false,
"is_valid": true
}
```'
tags:
- Coupons
security:
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ValidateCouponRequest'
examples:
validate:
summary: Validate a coupon code
value:
code: PROMO2024
responses:
'200':
description: Coupon preview.
content:
application/json:
schema:
$ref: '#/components/schemas/ValidateCouponResponse'
examples:
free_signature:
summary: Free signature coupon
value:
code: PROMO2024
kind: free_signature
description: 2 free signatures
signatures_count: 2
discount_will_apply: false
already_redeemed: false
is_valid: true
'400':
description: Invalid coupon code (length 1-64 required).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: Coupon code not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
$ref: '#/components/responses/InternalServerError'
/coupons/redeem:
post:
operationId: redeemCoupon
summary: Redeem a coupon
description: 'Redeems a `free_signature` coupon, converting the granted signatures into
credits added to the tenant''s balance.
## Important
- Only `free_signature` coupons can be redeemed here. `discount` coupons
must be applied directly at signature checkout and are rejected with `400`.
- Redemption is **idempotent**: a tenant can redeem a given coupon only
once (unique constraint on coupon + tenant). A repeat attempt returns `409`.
## Usage Example
```bash
curl -X POST https://api.faireplace.com/api/coupons/redeem \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d ''{ "code": "PROMO2024" }''
```
**Response**:
```json
{
"code": "PROMO2024",
"kind": "free_signature",
"signatures_count": 2,
"new_balance_cents": 150000,
"message": "2 signature(s) offerte(s) ajoutée(s) à votre solde"
}
```'
tags:
- Coupons
security:
- BearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RedeemCouponRequest'
examples:
redeem:
summary: Redeem a free-signature coupon
value:
code: PROMO2024
responses:
'200':
description: Coupon redeemed; credits added to the balance.
content:
application/json:
schema:
$ref: '#/components/schemas/RedeemCouponResponse'
examples:
success:
summary: Redeemed successfully
value:
code: PROMO2024
kind: free_signature
signatures_count: 2
new_balance_cents: 150000
message: 2 signature(s) offerte(s) ajoutée(s) à votre solde
'400':
description: 'Invalid request. Possible causes: invalid code format, the coupon is
a `discount` coupon (use it at checkout instead), the coupon is
inactive, expired, or saturated (max redemptions reached).
'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
discount_not_redeemable:
summary: Discount coupon cannot be redeemed here
value:
error:
code: VALIDATION_ERROR
message: 'Ce code est une réduction : utilisez-le directement lors du paiement de signature'
status: 400
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
description: Coupon code not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: The coupon has already been redeemed by this tenant.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'500':
$ref: '#/components/responses/InternalServerError'
components:
responses:
Forbidden:
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
UnprocessableEntity:
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalServerError:
description: Internal Server Error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
RedeemCouponRequest:
type: object
description: 'Request to redeem a coupon. Only `free_signature` coupons can be redeemed
here; `discount` coupons must be applied directly at checkout.
'
required:
- code
properties:
code:
type: string
minLength: 1
maxLength: 64
description: Coupon code to redeem.
example: PROMO2024
ValidateCouponRequest:
type: object
description: 'Request to preview a coupon without consuming it.
'
required:
- code
properties:
code:
type: string
minLength: 1
maxLength: 64
description: Coupon code to validate (case as provided by the user).
example: PROMO2024
RedeemCouponResponse:
type: object
description: 'Result of redeeming a `free_signature` coupon. The corresponding credit
value is added to the tenant''s credit balance.
'
required:
- code
- kind
- signatures_count
- new_balance_cents
- message
properties:
code:
type: string
description: Coupon code.
example: PROMO2024
kind:
type: string
description: Always `free_signature` for a redeemable coupon.
enum:
- free_signature
example: free_signature
signatures_count:
type: integer
format: int32
description: Number of free signatures granted by this redemption.
example: 2
new_balance_cents:
type: integer
format: int64
description: New credit balance in euro cents after the redemption.
example: 150000
message:
type: string
description: User-friendly confirmation message.
example: 2 signature(s) offerte(s) ajoutée(s) à votre solde
Error:
type: object
description: "The error envelope returned by every authenticated endpoint.\n\nTwo things are worth knowing before you write your error handling:\n\n- **`code` is a symbolic string, not a number.** The numeric HTTP status is\n in `status`. Branch on `code`: it is stable, and show `message`, which\n is written for humans and may be reworded without notice.\n- The public guest-signature endpoints use a **different, flatter shape**\n (`{ \"error_code\": …, \"message\": … }`, no `error` wrapper), because they\n are consumed by a page that has no session. Their responses document it\n inline.\n\nThe `X-Request-Id` response header carries the request identifier: quote it\nwhen reporting a problem. It is a header, not a body field.\n"
required:
- error
properties:
error:
type: object
required:
- code
- message
- status
properties:
code:
type: string
description: Stable symbolic code. Branch on this.
enum:
- NOT_FOUND
- UNAUTHORIZED
- VALIDATION_ERROR
- DATABASE_ERROR
- BUSINESS_ERROR
- STORAGE_ERROR
- CONFIG_ERROR
- FORBIDDEN
- CONFLICT
- PARSE_ERROR
- SERIALIZATION_ERROR
- AUTHENTICATION_ERROR
- AUTHORIZATION_ERROR
- EXTERNAL_SERVICE_ERROR
- RATE_LIMIT_EXCEEDED
- PAYMENT_REQUIRED
- PLAN_LIMIT_REACHED
- GONE
- BAD_REQUEST
- INTERNAL_ERROR
- INTERNAL_SERVER_ERROR
example: NOT_FOUND
message:
type: string
description: 'Human-readable explanation, most often in French. Safe to display,
not safe to parse.
'
example: Lease not found
status:
type: integer
description: The HTTP status code, repeated in the body.
example: 404
details:
type: object
additionalProperties: true
description: 'Extra machine-readable context. Only present on some errors: on
`RATE_LIMIT_EXCEEDED` it carries `retry_after_seconds`.
'
example:
retry_after_seconds: 12
CouponKind:
type: string
description: "Type of coupon.\n\n- `discount`: a Stripe discount applied directly at signature checkout\n (NOT redeemable via `POST /coupons/redeem`).\n- `free_signature`: grants a number of free signatures, converted into\n credits when redeemed.\n"
enum:
- discount
- free_signature
x-enumDescriptions:
discount: Stripe discount applied at checkout (use it directly when paying for a signature).
free_signature: Grants free signatures, added to the credit balance on redemption.
example: free_signature
ValidateCouponResponse:
type: object
description: 'Preview of a coupon. This endpoint does NOT consume the coupon; it only
reports whether it can be redeemed by the current tenant.
'
required:
- code
- kind
- discount_will_apply
- already_redeemed
- is_valid
properties:
code:
type: string
description: Coupon code.
example: PROMO2024
kind:
$ref: '#/components/schemas/CouponKind'
description:
type:
- string
- 'null'
description: Optional human-readable description of the coupon.
example: 2 free signatures
signatures_count:
type: integer
format: int32
description: 'Number of free signatures granted by the coupon.
Only present when `kind` is `free_signature` (omitted otherwise).
'
example: 2
discount_will_apply:
type: boolean
description: '`true` when `kind` is `discount`, meaning a Stripe discount will be
applied automatically at signature checkout.
'
example: false
already_redeemed:
type: boolean
description: Whether the current tenant has already redeemed this coupon.
example: false
is_valid:
type: boolean
description: '`true` if the coupon is active, not expired, not saturated
(max redemptions not reached) and not already redeemed by this tenant.
'
example: true
securitySchemes:
BearerAuth:
type: http
scheme: bearer
description: API key with fp_* prefix, passed as Bearer token
WorkerApiKey:
type: apiKey
in: header
name: X-API-Key
WorkerBearer:
type: http
scheme: bearer
bearerFormat: Worker