Skip to main content
POST
/
login
User Login
curl --request POST \
  --url https://api.example.com/login \
  --header 'Content-Type: application/json' \
  --data '
{
  "email": "<string>",
  "password": "<string>",
  "remember": true,
  "twoFactorCode": "<string>"
}
'
import requests

url = "https://api.example.com/login"

payload = {
"email": "<string>",
"password": "<string>",
"remember": True,
"twoFactorCode": "<string>"
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
email: '<string>',
password: '<string>',
remember: true,
twoFactorCode: '<string>'
})
};

fetch('https://api.example.com/login', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/login",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'email' => '<string>',
'password' => '<string>',
'remember' => true,
'twoFactorCode' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

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

func main() {

url := "https://api.example.com/login"

payload := strings.NewReader("{\n \"email\": \"<string>\",\n \"password\": \"<string>\",\n \"remember\": true,\n \"twoFactorCode\": \"<string>\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.example.com/login")
.header("Content-Type", "application/json")
.body("{\n \"email\": \"<string>\",\n \"password\": \"<string>\",\n \"remember\": true,\n \"twoFactorCode\": \"<string>\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.example.com/login")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"email\": \"<string>\",\n \"password\": \"<string>\",\n \"remember\": true,\n \"twoFactorCode\": \"<string>\"\n}"

response = http.request(request)
puts response.read_body
{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "uid": "6578a1b2c3d4e5f601234567",
  "userTitle": "Dr.",
  "firstName": "John",
  "lastName": "Doe",
  "twoFactorEnabled": false
}

Overview

The login endpoint authenticates a healthcare professional and returns a JWT token used to access protected endpoints. It is the primary authentication method for the MediSync platform.
No authentication is required to call this endpoint. Platform messages are returned in German.

Body Parameters

email
string
required
Registered email address. Validated as an email and normalized server-side.
password
string
required
Account password. Minimum 6 characters.
remember
boolean
default:"false"
If true, issues a 7-day token; otherwise the token is valid for 24 hours.
twoFactorCode
string
TOTP code (or a one-time backup code) for accounts with 2FA enabled. Omit it on the first call to receive the 202 2FA challenge, then resubmit with the code.

Response

success
boolean
true when authentication succeeds.
token
string
JWT token for authenticating subsequent requests.
uid
string
The authenticated user’s id.
userTitle
string
Medical title (Dr., Prof., …).
firstName
string
User’s first name.
lastName
string
User’s last name.
twoFactorEnabled
boolean
Whether the account has 2FA enabled.

Example Request

curl -X POST https://app.medisync.me/api/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "doctor@example.com",
    "password": "your_password",
    "remember": false
  }'
const response = await fetch('https://app.medisync.me/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'doctor@example.com',
    password: 'your_password',
    remember: false
  })
});
const data = await response.json();
import requests

response = requests.post('https://app.medisync.me/api/login', json={
    'email': 'doctor@example.com',
    'password': 'your_password',
    'remember': False
})
data = response.json()

Example Response

{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "uid": "6578a1b2c3d4e5f601234567",
  "userTitle": "Dr.",
  "firstName": "John",
  "lastName": "Doe",
  "twoFactorEnabled": false
}

Two-Factor Authentication

If the account has 2FA enabled and twoFactorCode is omitted, the endpoint returns 202 Accepted with a challenge instead of a token. Resubmit the same request including a valid twoFactorCode.
{
  "success": true,
  "requires2FA": true,
  "message": "Bitte geben Sie Ihren 2FA-Code ein."
}

Error Responses

{
  "error": "Bitte überprüfen Sie Ihre Eingaben."
}
{
  "failed": "Unauthorized Access",
  "error": "Ungültige E-Mail oder Passwort."
}
{
  "failed": "Email Not Verified",
  "error": "Bitte bestätigen Sie Ihre E-Mail-Adresse, bevor Sie sich anmelden.",
  "needsVerification": true
}
{
  "failed": "Invalid 2FA Code",
  "error": "Ungültiger 2FA-Code. Bitte versuchen Sie es erneut.",
  "requires2FA": true
}
{
  "error": "Zu viele Anmeldeversuche. Bitte versuchen Sie es in 15 Minuten erneut.",
  "rateLimited": true
}
Authentication failures use a failed label alongside error, while validation and rate-limit errors return only error. The API does not return invented English code values — branch on the HTTP status and the fields shown above.

Rate Limiting

Login is limited to 10 attempts per 15 minutes per email address. Exceeding the limit returns 429 with rateLimited: true; standard RateLimit-* headers (and Retry-After) are included.

Next Steps

Register

Create a new healthcare-professional account.

User Profile

Retrieve the authenticated user’s profile.