Goal
Restore a soft-deleted MexCep account using the magic-link delivered by the day-23 or day-29 warning emails. The link is single-use and signed by the server — clicking it inside the 30-day grace window restores the account instantly without contacting support.
Prerequisites
- Access to the email inbox that received the warning notice (subject: "Your MexCep account will be permanently deleted in N day(s)").
- The account must still be inside the 30-day GDPR grace window (
deleted_atnot yet 30 days old). - The token must not have been used already (single-use Redis guard).
Steps
1. Open the warning email
Look in your inbox for an email from noreply@mexcep.com with a subject similar to "Your MexCep account will be permanently deleted in 7 day(s)" or "...in 1 day(s)". The email body explains what is about to be erased and offers a Restore my account button.
2. Click the Restore button
The button deep-links to a landing page that automatically posts your signed token to POST /v1/auth/restore-account. No password or session cookie is required — the JWT carried in the link is the only credential and was signed by the MexCep server at the time the warning was generated.
3. (Optional) Call the endpoint directly
If you intercepted the token from the email URL (for example, by copying the ?token=... query string) you can also POST it directly:
curl -X POST 'https://api.example.com/v1/auth/restore-account' \
-H 'Content-Type: application/json' \
-d '{"token": "<jwt-from-email>"}'A successful response returns 200 OK with the restoration timestamp:
{
"data": {
"type": "account_restored",
"attributes": {
"user_id": "01948f32-b1df-7d75-8ddd-521703876668",
"restored_at": "2026-05-28T15:30:00Z",
"days_since_soft_delete": 23.45,
"message": "Account restored. Please log in normally to continue."
}
}
}4. Log in normally
Once restored, the account's status flips back to active and the tokens_invalidated_after timestamp is bumped — any cached JWTs from before deletion are invalidated. Log in normally with your email + password to continue.
Error responses
| Code | Error | Description |
|---|---|---|
| 422 | restore_token_required | The token field is missing from the request body. |
| 422 | restore_token_invalid | The JWT is malformed, has a bad signature, or its type claim is not self_restore. |
| 422 | restore_token_expired | The exp claim is in the past — the 30-day window already closed. |
| 422 | restore_token_used | A previous click already consumed this token. Each token is single-use. |
| 403 | admin_self_restore_not_allowed | Admin or owner accounts cannot be self-restored. Contact platform support. |
| 404 | user_not_restorable | Account does not exist, is already active, was already purged by the cron, or the 30-day window has elapsed. |
| 429 | rate_limit_exceeded | Too many attempts from the same IP. Wait a minute and retry. |
Notes
- Token expiry: the JWT's
expclaim is pinned to day 30 of the grace window, not the warning emit time. A day-23 token is therefore valid for ~7 more days; a day-29 token is valid for ~1 more day. - Single-use replay guard: a successful restore consumes the token's
jtiin Redis (restore_token_used:{jti}) with a 30-day TTL. A second click returns422 restore_token_used. - Magic-link delivery limitation: anyone with access to your inbox at the time of the warning email has the power to restore your account. Treat the email like a one-time password — do not forward it.
- Past the grace window: the cron purges the row and the only record remaining is a PII-redacted metric ledger entry. There is no recovery path from that point — contact platform support for backup restoration only as a last resort.