Skip to content
Coritan Docs

Organization API: Org Legacy Migration

Every Organization API operation tagged Org Legacy Migration.

View as Markdown

Base URL: https://api.coritan.com/api/v1. Paths below are complete.

To try these requests in the browser, open the interactive Organization API reference.

Method Path Summary
POST /api/v1/orgs/{org_slug}/legacy-migration/alerts Money or a chargeback the previous platform will not settle for a moved account
POST /api/v1/orgs/{org_slug}/legacy-migration/availability Whether an email address or a username is already taken in the organization
POST /api/v1/orgs/{org_slug}/legacy-migration/exchange Open a relayed sign-in code and return the session it holds
GET /api/v1/orgs/{org_slug}/legacy-migration/go Send the browser to the organization's storefront
POST /api/v1/orgs/{org_slug}/legacy-migration/redeem Move an account from the previous website into the organization
POST /api/v1/orgs/{org_slug}/legacy-migration/relay-login A sign-in typed on the previous platform for an account that lives here
POST /api/v1/orgs/{org_slug}/legacy-migration/state Legacy state
POST /api/v1/orgs/{org_slug}/legacy-migration/ticket What moving an account from the previous website will do, before anything moves

Money or a chargeback the previous platform will not settle for a moved account

Section titled Money or a chargeback the previous platform will not settle for a moved account

POST /api/v1/orgs/{org_slug}/legacy-migration/alerts

Money or a chargeback the previous platform will not settle for a moved account.

Signed by the previous platform. late_money is a payment or deposit that reached the old account after it moved; chargeback is a dispute on one of its old charges. Nothing is credited or deducted: the alert is written to the organization's audit log as customer.legacy_alert for staff to settle. Answers 404 for a customer this organization does not have.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
ok boolean

Whether an email address or a username is already taken in the organization

Section titled Whether an email address or a username is already taken in the organization

POST /api/v1/orgs/{org_slug}/legacy-migration/availability

Whether an email address or a username is already taken in the organization.

Signed by the previous platform, which asks before it registers an account or changes an address or a username, and refuses on true. Emails and usernames compare without regard to letter case, and names held by unclaimed placeholders count as taken. Answers 404 while the link is off and 401 for a request that is not signed with the shared secret.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
email_taken boolean
username_taken boolean

Open a relayed sign-in code and return the session it holds

Section titled Open a relayed sign-in code and return the session it holds

POST /api/v1/orgs/{org_slug}/legacy-migration/exchange

Open a relayed sign-in code and return the session it holds.

The storefront's /auth/callback sends the legacy_code from its URL fragment. The answer has the shape POST /auth/login answers: a session, or a two-factor step. A code opens for about a minute, and only for the organization that sealed it, and only once: a second open answers 400, as do a code that expired and anything else that is not a code.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required
code string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Send the browser to the organization's storefront

Section titled Send the browser to the organization's storefront

GET /api/v1/orgs/{org_slug}/legacy-migration/go

Send the browser to the organization's storefront.

The previous platform links here instead of to a storefront hostname, so the link keeps working when the storefront moves to another host. The redirect goes to the storefront address Coritan has registered for the organization: /migrate, /auth/callback, /login or /community. A ticket or sign-in code rides in the URL fragment, which the browser keeps across the redirect and never sends to a server. Answers 404 when no storefront address is registered.

Name In Type Required Description
org_slug path string yes
to query string, one of migrate, callback, signin, community no The storefront page to open: migrate, callback, signin or community. Default: signin.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Move an account from the previous website into the organization

Section titled Move an account from the previous website into the organization

POST /api/v1/orgs/{org_slug}/legacy-migration/redeem

Move an account from the previous website into the organization.

Send the ticket, accept_terms: true and, if the person chose one, the handle to use (3 to 20 letters, numbers or underscores). Without a handle the move uses the one POST /legacy-migration/ticket proposed. For merge_sign_in, send the existing account's bearer token too.

The previous website locks the old account and sends what moves: the password, so the old password signs in here; the names; the forum profile; the saved cards; and the balances, which become one wallet credit in USD. A merge keeps the existing account's password, username and settings, and takes the old account's forum threads. The answer holds the handle, whether the old account was merged into an existing one, credited_usd, the number of cards saved, and a session (or a two-factor step) in the shape POST /auth/login answers. Sending the same ticket again answers the same result and credits nothing twice. The repeat carries a session only for a ticket issued before the move, only within 5 minutes of the move, only while no session of the account was revoked since and its password is the one the move found, and for merge_sign_in only with that account's bearer token; otherwise session is null and the person signs in.

A merge into an account here needs no sign-in only when the old site's own record of the account shows that it verified the address (a flag and the date). When it does not, the answer is sign_in_required even though the ticket said merge_automatic, and the account's bearer token goes with the next try. Sign-in links that come along to an account whose address is not proven here are recorded in the move record, and the first proof of the address by email removes them.

Refusals answer with detail.code and detail.message: terms_required and invalid_ticket (400); sign_in_required (401); handle_unavailable (409, with reason and suggestion); not_eligible (409, with the blocking items the previous website lists); already_moved, email_blocked and limit_reached (409); old_site_unavailable and rate_unavailable (503), after which nothing has moved and the same request can be sent again later. Answers 404 while the organization is not moving accounts.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required
ticket string yes
accept_terms boolean yes
handle string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
result string
handle string
merged boolean
credited_usd string
cards integer
session Session or MfaStep or null

A sign-in typed on the previous platform for an account that lives here

Section titled A sign-in typed on the previous platform for an account that lives here

POST /api/v1/orgs/{org_slug}/legacy-migration/relay-login

A sign-in typed on the previous platform for an account that lives here.

Signed by the previous platform. It sends either customer_id (an account that moved) or login (an email address or username it does not know), with the password and the person's client_ip. The password is checked the way POST /auth/login checks it, and two-factor authentication is asked for in the same way. Failures count against the sign-in budget of client_ip and against the account.

client_ip must be an IPv4 or IPv6 address (anything else answers 422). The session keeps it, and so does the audit entry written for an accepted sign-in (customer.login_via_old_site).

ok carries a go_url whose fragment holds a sealed sign-in code that POST /legacy-migration/exchange opens once, within a minute. invalid covers a wrong password and an unknown login alike. social_only names an account with no password: providers lists the sign-in providers linked to it (discord, github, google or microsoft, in that order) and has_password is false, so the previous platform can tell the person what to use here. rate_limited asks the person to wait.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
result string, one of ok, invalid, social_only, rate_limited
go_url string or null
providers array of string
has_password boolean or null

POST /api/v1/orgs/{org_slug}/legacy-migration/state

Whether the previous platform's move is open, its forum is frozen and its sign-ups are closed.

Signed by the previous platform, with an empty object as the body. It asks every so often and keeps the answer for up to a minute. move_open opens its migrate section and lets someone who signs in on the storefront with an old account move it; forum_read_only makes its forum refuse new posts; signups_closed makes it refuse new accounts and new free servers and send people to sign up on the storefront, while existing accounts keep signing in. Coritan's staff set all three. Unlike the other signed routes this one answers while the link is off, with move_open: false and signups_closed: false, so the previous platform learns that the move closed and that the sign-up switch is off. Answers 404 while no shared secret is set and 401 for a request that is not signed with it.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
move_open boolean
forum_read_only boolean
signups_closed boolean
server_moves_open boolean

What moving an account from the previous website will do, before anything moves

Section titled What moving an account from the previous website will do, before anything moves

POST /api/v1/orgs/{org_slug}/legacy-migration/ticket

What moving an account from the previous website will do, before anything moves.

The storefront's move page sends the ticket from the link the previous website opened it with. The answer names the old account (username, email, providers) and says which case applies in account: new; placeholder when the account's forum threads are already here; merge_automatic when an account here has the same email address and both sites verified it; merge_sign_in when an account here has it but one site has not verified it, so the move needs that account's sign-in; or blocked when the account here is banned, suspended or closed.

handle proposes the username for a new account or a placeholder: the old username when it fits the username rules and nobody here uses it, else a free suggestion, with reason saying why the old one could not be kept. A merge keeps the existing account's username, so handle.value is then null. terms_url and privacy_url link the organization's terms of service and privacy policy. Nothing is locked or written.

Refusals answer with detail.code and detail.message: invalid_ticket (400) for a ticket that is altered, of another kind or expired, and already_moved (409) for an account that has already moved here. Answers 404 while the organization is not moving accounts.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required
ticket string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fields of a 200 response:

Field Type
username string
email string
providers array of string
account string, one of new, placeholder, merge_automatic, merge_sign_in, blocked
handle HandleVerdict
handle.value string or null
handle.available boolean
handle.reason string or null
terms_url string or null
privacy_url string or null