Auth

AdminUpdated Sep 24, 2026
POSThttps://shippified.net/api/auth/register
Register a new workspace.
Request body application/json
{
  "email": "string",
  "password": "string",
  "displayName": "string"
}
Responses
201 Workspace created, session minted.
{
  "token": "string",
  "user": {}
}
400 Invalid email or password.
409 Email already registered.
429 Rate limit exceeded.
Code samples
cURL
curl -X POST "https://shippified.net/api/auth/register" \
  -H "Content-Type: application/json" \
  -d '{"email":"string","password":"string","displayName":"string"}'
TypeScript
const res = await fetch('https://shippified.net/api/auth/register', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"email":"string","password":"string","displayName":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://shippified.net/api/auth/register",
    headers={
    "Content-Type": "application/json",
    },
    json={"email": "string", "password": "string", "displayName": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://shippified.net/api/auth/register", strings.NewReader(`{"email":"string","password":"string","displayName":"string"}`))
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/register');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"email":"string","password":"string","displayName":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/register')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = '{"email":"string","password":"string","displayName":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/register"))
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"email\":\"string\",\"password\":\"string\",\"displayName\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://shippified.net/api/auth/login
Log in to an existing workspace.
Request body application/json
{
  "email": "string",
  "password": "string"
}
Responses
200 Session minted.
401 Invalid credentials.
429 Rate limit exceeded.
Code samples
cURL
curl -X POST "https://shippified.net/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"email":"string","password":"string"}'
TypeScript
const res = await fetch('https://shippified.net/api/auth/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"email":"string","password":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://shippified.net/api/auth/login",
    headers={
    "Content-Type": "application/json",
    },
    json={"email": "string", "password": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://shippified.net/api/auth/login", strings.NewReader(`{"email":"string","password":"string"}`))
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/login');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"email":"string","password":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/login')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = '{"email":"string","password":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/login"))
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"email\":\"string\",\"password\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://shippified.net/api/auth/me
Current user + workspace state.
Responses
200 OK
401 Not authenticated.
Code samples
cURL
curl -X GET "https://shippified.net/api/auth/me"
TypeScript
const res = await fetch('https://shippified.net/api/auth/me', {
  method: 'GET',
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://shippified.net/api/auth/me",
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://shippified.net/api/auth/me", nil)
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/me');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/me')
req = Net::HTTP::Get.new(uri)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/me"))
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
DELETEhttps://shippified.net/api/auth/session
Revoke current session token.
Responses
200 Revoked.
Code samples
cURL
curl -X DELETE "https://shippified.net/api/auth/session"
TypeScript
const res = await fetch('https://shippified.net/api/auth/session', {
  method: 'DELETE',
});
const data = await res.json();
Python
import requests

res = requests.request(
    "DELETE",
    "https://shippified.net/api/auth/session",
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://shippified.net/api/auth/session", nil)
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/session');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/session')
req = Net::HTTP::Delete.new(uri)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/session"))
    .method("DELETE", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://shippified.net/api/auth/providers
Which sign-in options this deployment has enabled.

Public. The sign-in page calls this to decide which SSO buttons to show and whether to render a Turnstile challenge.

Responses
200 OK
{
  "google": true,
  "discord": true,
  "discordSlug": null,
  "turnstile": true,
  "turnstileSiteKey": null,
  "billingEnabled": true
}
Code samples
cURL
curl -X GET "https://shippified.net/api/auth/providers"
TypeScript
const res = await fetch('https://shippified.net/api/auth/providers', {
  method: 'GET',
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://shippified.net/api/auth/providers",
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://shippified.net/api/auth/providers", nil)
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/providers');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/providers')
req = Net::HTTP::Get.new(uri)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/providers"))
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://shippified.net/api/auth/forgot-password
Email a password-reset link.

Public. Always answers `{ ok: true }` for a well-formed request, whether or not an account uses that email, so it can't be used to find out who has an account. When one does (and outbound mail is configured) a link valid for 1 hour is sent. Shares the 10/min per-IP auth rate limit.

Request body application/json
{
  "email": "string",
  "turnstileToken": "string"
}
Responses
200 Accepted.
{
  "ok": true
}
400 Missing email, or the Turnstile check failed.
{
  "error": "string"
}
429 Rate limit exceeded. See `Retry-After`.
Code samples
cURL
curl -X POST "https://shippified.net/api/auth/forgot-password" \
  -H "Content-Type: application/json" \
  -d '{"email":"string","turnstileToken":"string"}'
TypeScript
const res = await fetch('https://shippified.net/api/auth/forgot-password', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"email":"string","turnstileToken":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://shippified.net/api/auth/forgot-password",
    headers={
    "Content-Type": "application/json",
    },
    json={"email": "string", "turnstileToken": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://shippified.net/api/auth/forgot-password", strings.NewReader(`{"email":"string","turnstileToken":"string"}`))
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/forgot-password');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"email":"string","turnstileToken":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/forgot-password')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = '{"email":"string","turnstileToken":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/forgot-password"))
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"email\":\"string\",\"turnstileToken\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://shippified.net/api/auth/reset-password
Set a new password using the token from the reset email.

Public. On success every existing session for the account is revoked and a fresh session is returned, so the caller is signed in straight away. Shares the 10/min per-IP auth rate limit.

Request body application/json
{
  "token": "string",
  "password": "string",
  "turnstileToken": "string"
}
Responses
200 Password changed; new session minted.
{
  "ok": true,
  "token": "string",
  "user": {},
  "state": {}
}
400 Missing token, password under 8 characters, token invalid or expired, or the Turnstile check failed.
{
  "error": "string"
}
429 Rate limit exceeded. See `Retry-After`.
Code samples
cURL
curl -X POST "https://shippified.net/api/auth/reset-password" \
  -H "Content-Type: application/json" \
  -d '{"token":"string","password":"string","turnstileToken":"string"}'
TypeScript
const res = await fetch('https://shippified.net/api/auth/reset-password', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"token":"string","password":"string","turnstileToken":"string"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://shippified.net/api/auth/reset-password",
    headers={
    "Content-Type": "application/json",
    },
    json={"token": "string", "password": "string", "turnstileToken": "string"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("POST", "https://shippified.net/api/auth/reset-password", strings.NewReader(`{"token":"string","password":"string","turnstileToken":"string"}`))
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/reset-password');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"token":"string","password":"string","turnstileToken":"string"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/reset-password')
req = Net::HTTP::Post.new(uri)
req['Content-Type'] = 'application/json'
req.body = '{"token":"string","password":"string","turnstileToken":"string"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/reset-password"))
    .header("Content-Type", "application/json")
    .method("POST", BodyPublishers.ofString("{\"token\":\"string\",\"password\":\"string\",\"turnstileToken\":\"string\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
POSThttps://shippified.net/api/auth/resend-verify
Resend the email-verification link to the signed-in account.

Issues a new link (valid 24 hours), replacing any earlier one. Mail failures come back in the body with a 200, not as an error status.

Responses
200 `already: true` when the email is already verified. Otherwise `ok` reports whether the mail was handed off, with `reason` when it wasn't.
{
  "ok": true,
  "already": true,
  "reason": "not_configured"
}
401 Not authenticated.
Code samples
cURL
curl -X POST "https://shippified.net/api/auth/resend-verify"
TypeScript
const res = await fetch('https://shippified.net/api/auth/resend-verify', {
  method: 'POST',
});
const data = await res.json();
Python
import requests

res = requests.request(
    "POST",
    "https://shippified.net/api/auth/resend-verify",
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://shippified.net/api/auth/resend-verify", nil)
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/resend-verify');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/resend-verify')
req = Net::HTTP::Post.new(uri)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/resend-verify"))
    .method("POST", BodyPublishers.noBody())
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
GEThttps://shippified.net/api/auth/verify
Confirm an email address (the link in the verification email).

Public browser endpoint. Always answers with a redirect: `/home?verify=ok` on success, `/auth?verify=missing` without a token, `/auth?verify=invalid` for an unknown or expired token.

Parameters
NameInTypeRequiredDescription
tokenquerystringyes
Responses
302 Redirect to the app; the `verify` query parameter carries the result.
Code samples
cURL
curl -X GET "https://shippified.net/api/auth/verify?token="
TypeScript
const res = await fetch('https://shippified.net/api/auth/verify?token=', {
  method: 'GET',
});
const data = await res.json();
Python
import requests

res = requests.request(
    "GET",
    "https://shippified.net/api/auth/verify?token=",
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://shippified.net/api/auth/verify?token=", nil)
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://shippified.net/api/auth/verify?token=');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://shippified.net/api/auth/verify?token=')
req = Net::HTTP::Get.new(uri)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://shippified.net/api/auth/verify?token="))
    .GET()
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Was this page helpful?