Android engineer (Kotlin) assessment task
This task forms part of our practical seniority assessment for Android roles. It is deliberately limited in scope and is intended to support a focused technical discussion.
Purpose
You are asked to build a small Android application for managing payments.
The goal is not to produce the most elaborate solution. We are looking for a correct, working implementation with sensible technical choices, clear scope control, and a practical approach to business logic and user interaction. Keep it focused and avoid over-engineering.
Time reference
We use this task with internal timing benchmarks as part of our seniority assessment.
For this specific task, our benchmark is as follows:
- a senior-level engineer should usually be able to reach a working baseline in about 4 hours;
- a mid-level engineer will typically need up to 12 hours;
- if it takes materially longer than 12 hours, we would usually treat that as junior-level execution for this scope.
These timings come from our own calibration of the task. They are a practical reference point, not a decision on their own. A working solution still comes first. We consider timing alongside correctness, implementation quality, scope control, and technical reasoning.
For broader context on how timing fits into the process, see How we assess seniority.
Use of tools
This task is intended to reflect your own practical level of execution within the stated scope and timing benchmark.
You may use standard documentation, reference materials, and search tools such as Google while working on it. AI tools are not allowed. This includes code generation tools, AI assistants, and any other system used to generate, rewrite, suggest, or complete code or technical content on your behalf.
The task must represent your own work.
Technical baseline
Use the following stack:
- Kotlin
- Jetpack Compose
- ViewModel with Kotlin coroutines / Flow
- Retrofit, Ktor Client, or OkHttp
- Material 3
You may use additional libraries if needed, but the solution should remain proportionate to the scope of the task.
Task overview
Implement a small Android application for managing payments through the provided REST API.
The application must support:
- creating a payment;
- viewing existing payments;
- updating a payment;
- deleting a payment;
- marking a payment as completed;
- marking a payment as failed.
A simple, functional layout is fully sufficient.
Payment model
The UI should work with at least the following fields:
idamountcurrencydebtorAccountcreditorAccountstatus
The following rules apply:
statusis managed by the backend;statusmust not be editable by the user;- newly created payments are expected to have status
CREATED.
Functional requirements
The application must include the following.
Payment form
A form for creating and updating payments with at least these fields:
- amount
- currency
- debtor account
- creditor account
The exact UI flow is up to you, provided the required operations are supported clearly.
Validation
Implement client-side validation, including at minimum:
- required fields;
- amount must be greater than 0.
Payment list
Display a list of existing payments.
The list should show at least:
- id
- amount
- currency
- debtor account
- creditor account
- status
Actions
The user must be able to:
- create a payment;
- edit a payment;
- delete a payment;
- mark a payment as completed;
- mark a payment as failed.
API integration
The application should work with the REST API provided by the back-end service.
The expected endpoints are:
POST /payments— create paymentGET /payments— list paymentsGET /payments/{id}— get payment by IDPUT /payments/{id}— update paymentDELETE /payments/{id}— delete paymentPOST /payments/{id}/complete— mark payment as completedPOST /payments/{id}/fail— mark payment as failed
A reference mock back-end implementing this API is provided together with the task (click here to download). It requires only Node.js and starts with a single command; see its README for details. If you prefer to mock responses in your own way instead, explain your approach in the README.
Example create request:
{
"amount": 100.0,
"currency": "EUR",
"debtorAccount": "DE123456789",
"creditorAccount": "DE987654321"
}
Example response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"amount": 100.0,
"currency": "EUR",
"debtorAccount": "DE123456789",
"creditorAccount": "DE987654321",
"status": "CREATED",
"createdAt": "2026-04-14T10:15:30Z"
}
UI expectations
The UI does not need to be pixel-perfect or visually polished. We are looking for clear structure, reasonable usability, readable forms, a readable list, and clean handling of loading, empty, and error states.
The application should make state changes and unavailable actions understandable to the user. Where a payment is in a state that should no longer be editable, the interface should handle that clearly rather than presenting the action as if it were still available.
UI state should survive configuration changes such as screen rotation without losing user input.
Runtime and configuration
The project must run locally with standard Gradle commands, on an emulator or a physical device.
The API base URL should be configured in a simple, documented way.
Build and run requirements
The project must include:
- a working local development setup;
- build instructions;
- run instructions;
- a
READMEexplaining:- how to install dependencies;
- how to run the project;
- how to build the project.
You may also include short design notes if they help.
Out of scope
The following are not required for this exercise:
- offline mode, local database, or caching;
- authentication or authorisation;
- push notifications;
- pagination;
- tablet or adaptive layouts;
- a dependency injection framework unless you believe it is proportionate to the task;
- automated tests.
Keep the solution simple and focused.
What we pay attention to
The first requirement is that the solution works.
Beyond that, we look at whether the implementation is correct, pragmatic, clearly structured, and appropriately scoped. We also look at whether the form handling, validation, state handling, and API integration are sensible for the size of the task, and how clearly you can explain your decisions during the technical discussion.
Assessment materials and confidentiality
This task and the related assessment materials are provided solely for use in our hiring process. The task brief, its structure, examples, and associated assessment methodology are proprietary to us and must not be copied, shared, republished, distributed, or made public in any form, whether in full or in part. This includes posting the task, extracts from it, or materials that reproduce its substance on websites, social platforms, public code repositories, forums, blogs, or training libraries.
Any solution prepared in response to this task must be submitted for assessment purposes only and must not be published together with the task content or in a way that discloses the task itself. If you would like to refer to your work privately as part of a future application process, please do so only in a way that does not disclose or reproduce our assessment materials.
Related page
For background on how this task fits into our hiring process, including how timing is used as one benchmark, see How we assess seniority.