> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fincode.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# Login

> Authenticate users and obtain access tokens for API requests

Authenticate users with email and password to obtain JWT access and refresh tokens. This endpoint supports all user roles: MANAGER, AGENT, CASHIER, and CUSTOMER, etc.

## Request Headers

<ParamField header="Content-Type" type="string" required default="application/json">
    Must be `application/json`
</ParamField>

<ParamField header="platform" type="string" required default="fincode">
    Platform identifier. Use `fincode`
</ParamField>

<ParamField header="uuid" type="string" required default="200">
    Unique request identifier. Use `200`
</ParamField>

## Request Body

<ParamField body="email" type="string" required>
      User's email address registered in the system
</ParamField>

<ParamField body="currentPassword" type="string" required>
      User's password (minimum 8 characters)
</ParamField>

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PUT "https://remitjunction.fincode.software/api/v6/services/securitymanagement/login" \
    -H "Content-Type: application/json" \
    -H "platform: fincode" \
    -H "uuid: 200" \
    -d '{
      "email": "manager@yourcompany.com",
      "currentPassword": "Password@1"
    }'
  ```

  ```java Java theme={null}
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;

  public class FinCodeLogin {

      public static class LoginRequest {
          public String email;
          public String currentPassword;

          public LoginRequest(String email, String password) {
              this.email = email;
              this.currentPassword = password;
          }
      }

      public static class LoginResponse {
          public String access_token;
          public int expires_in;
          public String refresh_token;
          public User user;

          public static class User {
              public String id;
              public String email;
              public String role;
              public String tenant_id;
              public String[] permissions;
          }
      }

      public static LoginResponse login(String email, String password) throws Exception {
          HttpClient client = HttpClient.newHttpClient();
          Gson gson = new Gson();

          LoginRequest loginRequest = new LoginRequest(email, password);
          String requestBody = gson.toJson(loginRequest);

          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("https://remitjunction.fincode.software/api/v6/services/securitymanagement/login"))
              .header("Content-Type", "application/json")
              .header("platform", "fincode")
              .header("uuid", "200")
              .PUT(HttpRequest.BodyPublishers.ofString(requestBody))
              .build();

          HttpResponse<String> response = client.send(
              request,
              HttpResponse.BodyHandlers.ofString()
          );

          if (response.statusCode() == 200) {
              LoginResponse loginResponse = gson.fromJson(response.body(), LoginResponse.class);

              System.out.println("Login successful!");
              System.out.println("User Role: " + loginResponse.user.role);
              System.out.println("Access Token: " + loginResponse.access_token);

              return loginResponse;
          } else {
              throw new Exception("Login failed: " + response.body());
          }
      }

      public static void main(String[] args) {
          try {
              LoginResponse response = login("manager@yourcompany.com", "Password@1");
              String accessToken = response.access_token;
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  ```
</CodeGroup>

***

## Error Handling

<AccordionGroup>
  <Accordion title="Invalid Credentials (401)" icon="circle-xmark">
    **Cause**: Email or password is incorrect

    **Solution**:

    * Verify email address is correct
    * Check password is entered correctly
    * Use password reset if forgotten
    * Contact support if issue persists
  </Accordion>

  <Accordion title="Account Locked (403)" icon="lock">
    **Cause**: Multiple failed login attempts

    **Solution**:

    * Wait for the lockout period to expire
    * Contact your administrator to unlock the account
    * Use the "Forgot Password" flow to reset password
  </Accordion>

  <Accordion title="User Not Found (404)" icon="user-xmark">
    **Cause**: Email address not registered in the system

    **Solution**:

    * Verify the email address
    * Check if the user exists in your tenant
    * Contact administrator to create the user account
  </Accordion>
</AccordionGroup>

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Token Storage" icon="database">
    * Store tokens securely (encrypted storage)
    * Use environment variables for tokens
    * Clear tokens on logout
  </Card>

  <Card title="Token Refresh" icon="rotate">
    * Implement automatic token refresh
    * Refresh before expiration (5 min buffer)
  </Card>

  <Card title="Error Handling" icon="shield">
    * Implement retry logic
    * User-friendly messages
  </Card>

  <Card title="Security" icon="lock">
    * CSRF protection
    * Set secure cookie flags
  </Card>
</CardGroup>

***

## Testing in Sandbox

Use these test credentials in your sandbox environment:

```javascript theme={null}
const testCredentials = {
  manager: {
    email: "hello@remitjunction.co.uk",
    password: "Password@1",
  },
  agent: {
    email: "hello+2@remitjunction.co.uk",
    password: "Password@1",
  },
  cashier: {
    email: "excel.nwachukwu+662@fincode.co.uk",
    password: "PQW7ERMP",
  },
  customer: {
    email: "excel.nwachukwu+662@fincode.co.uk",
    password: "Password@1",
  },
};
```

<Warning>
  These credentials only work in sandbox. Never use test credentials in
  production.
</Warning>


## OpenAPI

````yaml PUT /securitymanagement/login
openapi: 3.0.0
info:
  title: FinCode API
  version: v6
servers:
  - url: https://{tenant}.fincode.software/api/v6/services
    description: API v6
    variables:
      tenant:
        default: remitjunction
        description: Enter your tenant subdomain
  - url: https://{tenant}.fincode.software/api/v1/services
    description: API v1
    variables:
      tenant:
        default: finlend
        description: Enter your tenant subdomain
  - url: https://api.stag.songhaiexchange.io
    description: Songhai Exchange API
security: []
paths:
  /securitymanagement/login:
    put:
      summary: Login
      description: Authenticate users and obtain access tokens
      operationId: login
      parameters:
        - $ref: '#/components/parameters/platformHeader'
        - $ref: '#/components/parameters/uuidHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                currentPassword:
                  type: string
              required:
                - email
                - currentPassword
      responses:
        '200':
          description: Successful login
components:
  parameters:
    platformHeader:
      in: header
      name: platform
      schema:
        type: string
        default: fincode
      required: true
    uuidHeader:
      in: header
      name: uuid
      schema:
        type: string
        default: '200'
      required: true

````