Skip to content

Use CAWS, CARP's server

CAWS (CARP Web Services) is CARP’s own server. With CAWS, the researcher does most of the work in a web browser, and the app mostly just signs in and follows instructions.

flowchart LR
    A["Researcher creates<br/>the study in the portal"]
    A -->|Invitation by email| C["Participant signs in<br/>with their account"]
    A -->|Self sign-up| E["Participant enters<br/>the study code<br/>or scans the QR code"]
    C --> H["App gets the study,<br/>collects data and<br/>uploads it to CAWS"]
    E --> H
    H --> J["Researcher<br/>downloads the data"]

Notice the difference from the on-phone setup: the protocol lives on the server, not in the app. Researchers can change what’s collected without releasing a new app.

Invitation by email Self sign-up with a code
How it works The researcher invites each person by email. They sign in with their own account. The researcher turns on self sign-up and gets a 5-letter study code and a QR code. Anyone with the code can join.
Participants are Known by email Anonymous, no email or password needed
Good for Studies where you need to know who is who Classrooms, events and public studies, where many people join at once
Limits One invitation per person The researcher sets a maximum number of participants, and can turn sign-up off at any time

To use CAWS you need access to the CARP web portal. There are three ways in:

  • DTU researchers can use the CAWS server hosted by DTU Health Tech.
  • Have a study in mind? Reach out. Whoever you are, if you’re planning a good study, contact us on Discord or at support@carp.dk and we’ll find a way to support it.
  • Run your own copy. CAWS is open source: carp-webservices-spring.
  1. Add the CAWS packages:

    Terminal window
    flutter pub add carp_webservices carp_backend

    On Android, these need a newer minimum version. In android/app/build.gradle.kts, set minSdk = 26.

  2. Point the app at the server and sign in.

    import 'package:carp_webservices/carp_auth/carp_auth.dart';
    import 'package:carp_webservices/carp_services/carp_services.dart';
    import 'package:carp_backend/carp_backend.dart';
    // DTU's CAWS; use 'dev.carp.dk' while testing.
    final uri = Uri(scheme: 'https', host: 'carp.computerome.dk');
    await CarpAuthService().configure(
    CarpAuthProperties(
    authURL: uri,
    clientId: 'your-client-id',
    redirectURI: Uri.parse('your-app://auth'),
    anonymousRedirectURI: Uri.parse('your-app:/anonymous'), // only for study codes
    discoveryURL: uri.replace(pathSegments: ['auth', 'realms', 'Carp']),
    ),
    );
    CarpService().configure(CarpApp(name: 'My study app', uri: uri));

    Then sign the participant in, depending on how they joined:

    Shows the CARP login page, where the participant signs in with their account:

    await CarpAuthService().authenticate();
  3. Turn on the CAWS services. Enable fetching studies and uploading data:

    CarpParticipationService().configureFrom(CarpService());
    CarpDeploymentService().configureFrom(CarpService());
    DataManagerRegistry().register(CarpDataManagerFactory());
  4. Get the participant’s study and start it. Instead of writing a protocol in the app, ask CAWS which study this person has joined. This is the same for both ways of joining:

    final invitations =
    await CarpParticipationService().getActiveParticipationInvitations();
    if (invitations.isEmpty) return; // not part of any study yet
    final study = SmartphoneStudy.fromInvitation(invitations.first);
    final client = SmartPhoneClientManager();
    await client.configure(deploymentService: CarpDeploymentService());
    await client.addStudy(study);
    await client.tryDeployment(study.studyDeploymentId, study.deviceRoleName);
    client.resume();

Because the study’s protocol says to send data to CAWS, the app now saves data on the phone and uploads it automatically, every 10 minutes by default. If the phone is offline, it waits until it’s back online.

Full details: the carp_backend package.

More detail: Data Managers → CAWS.