---
title: "From Sign-up to ATP"
description: "Create an account, invite people, and produce a client, project, SOW and acceptance test plan from a terminal or an MCP client"
---

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

# From Sign-up to ATP

This page goes from nothing to an acceptance test plan (ATP). Each step shows both routes:

- **Terminal** uses `curl` and `jq`. It works anywhere an agent can run shell commands, including Pi.
- **MCP** is what to ask an assistant connected through [MCP](/integrations/mcp-setup/), with the tool it calls.

Terminal commands build on each other, so run them in one shell session or keep the IDs they print.

1. **Create your account**

   ### Terminal

   Set the addresses and your details. Use an email address you control. Password sign-in needs at least 8 characters.

   ```bash
   export TANDA_APP=https://www.testandaccept.com
   export TANDA_API=https://api.testandaccept.com/api/rest
   export TANDA_JAR="$(mktemp)"
   export TANDA_NAME="Ada Lovelace"
   export TANDA_EMAIL="ada@example.com"
   export TANDA_PASSWORD="$(openssl rand -base64 24)"
   ```

   Save the generated password in your password manager, then sign up. The session is kept in the cookie file:

   ```bash
   curl -sS --fail-with-body -b "$TANDA_JAR" -c "$TANDA_JAR" "$TANDA_APP/api/auth/sign-up/email" \
     -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg name "$TANDA_NAME" --arg email "$TANDA_EMAIL" --arg password "$TANDA_PASSWORD" \
       '{name: $name, email: $email, password: $password}')" | jq '.user | {id, email}'
   ```

   Already have an account? Send the same request to `/api/auth/sign-in/email`, without `name`. If you sign in with Google, GitHub or Microsoft, skip to [the next step](#create-a-token) and [create your token on the Developer page](/agents/api-tokens/#create-a-token-in-the-app).

   Sign-up and sign-in allow only a few attempts every few seconds. If you get a `429`, wait 10 seconds and try again.

   ### MCP

   [Add the server to your client](/integrations/mcp-setup/). The first time it connects, your client opens the Tanda sign-in page in your browser. Choose to sign up, or sign in if you already have an account, then approve access.

   An account can't be created over MCP, because connecting needs an account first.
2. **Create an organization**

   An organization holds your clients and projects, and your team.

   ### Terminal

   Create it, make it your active organization, and set up its file storage:

   ```bash
   export TANDA_ORG_NAME="Analytical Engines"
   export TANDA_ORG_SLUG="analytical-engines-$(openssl rand -hex 3)"

   export TANDA_ORG_ID="$(curl -sS --fail-with-body -b "$TANDA_JAR" -c "$TANDA_JAR" \
     "$TANDA_APP/api/auth/organization/create" \
     -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg name "$TANDA_ORG_NAME" --arg slug "$TANDA_ORG_SLUG" '{name: $name, slug: $slug}')" \
     | jq -r .id)"

   curl -sS --fail-with-body -o /dev/null -b "$TANDA_JAR" -c "$TANDA_JAR" \
     "$TANDA_APP/api/auth/organization/set-active" \
     -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg id "$TANDA_ORG_ID" '{organizationId: $id}')"

   curl -sS -o /dev/null -w 'File storage: %{http_code}\n' -b "$TANDA_JAR" "$TANDA_APP/api/organizations/provision" \
     -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg id "$TANDA_ORG_ID" --arg name "$TANDA_ORG_NAME" \
       '{organizationId: $id, organizationName: $name}')"

   echo "Organization: $TANDA_ORG_ID"
   ```

   The last request sets up file storage and should print `200`. If it fails, you can still carry on with the rest of this page.

   ### MCP

   Open [testandaccept.com/organization-setup](https://www.testandaccept.com/organization-setup) in your browser to create one. Then ask:

   > Which Tanda organizations can I work in?

   The assistant calls `list_organizations`. If you belong to more than one, tell it which to use and it calls `set_default_organization`.
3. **Create a token**

   ### Terminal

   Create an [API token](/agents/api-tokens/). It's only shown once, and every request after this uses it:

   ```bash
   export TANDA_TOKEN="$(curl -sS --fail-with-body -b "$TANDA_JAR" "$TANDA_APP/api/api-token" \
     -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
     -d '{"name": "agent"}' | jq -r .token)"
   ```

   Save it in your secrets manager. Check that it works:

   ```bash
   curl -sS --fail-with-body "$TANDA_API/projects" -H "Authorization: Bearer $TANDA_TOKEN" | jq .total
   ```

   A new organization has no projects yet, so this prints `0`.

   ### MCP

   Nothing to do: your client signed in when it connected.
4. **Create a client and a project**

   ### Terminal

   ```bash
   export TANDA_CLIENT_ID="$(curl -sS --fail-with-body "$TANDA_API/clients" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{"name": "Globex", "industry": "Manufacturing"}' | jq -r .id)"

   export TANDA_PROJECT_ID="$(curl -sS --fail-with-body "$TANDA_API/projects" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg client "$TANDA_CLIENT_ID" '{name: "Customer portal", clientId: $client}')" \
     | jq -r .id)"

   echo "Client: $TANDA_CLIENT_ID  Project: $TANDA_PROJECT_ID"
   ```

   ### MCP

   > Create a client called Globex in manufacturing, and a project for them called Customer portal.

   The assistant calls `create_client` and then `create_project`.
5. **Invite people**

   There are two kinds of invitation. A project invitation gives someone access to one project. An organization invitation makes them a member of your organization.

   ### Terminal

   **To a project.** Access levels are `owner`, `editor`, `approver`, `viewer` and `follower`. Tanda emails the person. If an account has already verified that address, they're added straight away and notified:

   ```bash
   curl -sS --fail-with-body "$TANDA_API/projects/$TANDA_PROJECT_ID/invitations" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{"email": "grace@example.com", "accessLevel": "editor", "message": "Please review the plan"}'
   ```

   **To the organization.** Roles are `admin` and `member`, and you must be an admin. Tanda does not email this one. Send the person the `acceptUrl` from the response:

   ```bash
   curl -sS --fail-with-body "$TANDA_API/organization/invitations" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{"email": "grace@example.com", "role": "member"}' | jq -r .acceptUrl
   ```

   The link lasts 7 days and only works for an account with the invited email address.

   ### MCP

   > Invite <grace@example.com> to Customer portal as an editor.

   The assistant calls `invite_project_member`, which **sends no email**. It gives you an `acceptUrl`, and you send that to the person. The link lasts 7 days and only works for an account with the invited email address.

   Organization invitations aren't available over MCP. Use the Terminal route, or invite people from your organization settings in the app.
6. **Write the statement of work**

   A SOW holds task items. Each item has acceptance criteria, and each criterion has the tests that prove it. Add one of each here, and repeat for the rest of your work.

   ### Terminal

   ```bash
   export TANDA_SOW_ID="$(curl -sS --fail-with-body "$TANDA_API/projects/$TANDA_PROJECT_ID/sows" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{"title": "Phase 1", "description": "Customers sign in and see their orders."}' | jq -r .id)"

   export TANDA_ITEM_ID="$(curl -sS --fail-with-body "$TANDA_API/task-items" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d "$(jq -n --arg sow "$TANDA_SOW_ID" '{sowId: $sow, title: "Sign-in page"}')" | jq -r .id)"

   export TANDA_CRITERION_ID="$(curl -sS --fail-with-body "$TANDA_API/task-items/$TANDA_ITEM_ID/criteria" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{"title": "Customers can sign in", "acceptanceCriteria": "Valid credentials open the orders page."}' \
     | jq -r .id)"
   ```

   Add a test with its procedure:

   ```bash
   curl -sS --fail-with-body "$TANDA_API/criteria/$TANDA_CRITERION_ID/tests" \
     -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' \
     -d '{
       "title": "Sign in with valid credentials",
       "testType": "manual",
       "priority": "high",
       "testFormat": "procedural",
       "sections": [{
         "title": "Execution",
         "functions": [{
           "title": "Sign in",
           "prerequisites": "An active customer account exists",
           "steps": [
             {"step": 1, "action": "Open /signin", "expected": "The sign-in form shows"},
             {"step": 2, "action": "Submit valid credentials", "expected": "The orders page opens"}
           ]
         }]
       }]
     }' | jq '{id, title}'
   ```

   ### MCP

   > Create a SOW called Phase 1 in Customer portal from this brief: customers sign in and see their orders. Add task items, acceptance criteria and a detailed test for each criterion.

   The assistant calls `create_sow`, `create_task_item`, `create_acceptance_criterion` and `create_test`. For a long brief, ask it to use `start_sow_generation` instead, which drafts the SOW and waits for your approval before saving.

   To find what's missing, ask it to check coverage. It calls `analyze_coverage`.
7. **Produce the ATP**

   An ATP isn't a separate record. Tanda [generates it from the SOW](/concepts/acceptance-test-plans/), so it always matches the current tests. A criterion with no test has nothing to run, so check that every criterion has one.

   ### Terminal

   As Markdown, or as a PDF to send to your client:

   ```bash
   curl -sS --fail-with-body \
     "$TANDA_APP/api/sow/$TANDA_SOW_ID/export?format=markdown&variant=procedure" \
     -H "Authorization: Bearer $TANDA_TOKEN"

   curl -sS --fail-with-body -o atp.pdf \
     "$TANDA_APP/api/sow/$TANDA_SOW_ID/export?format=pdf&variant=procedure" \
     -H "Authorization: Bearer $TANDA_TOKEN"
   ```

   Once tests have run, `variant=report` adds their results.

   ### MCP

   > Give me the acceptance test plan for Phase 1.

   The assistant calls `get_acceptance_test_plan`, which returns the plan as Markdown, along with any criteria that have no test. For a PDF, use the Terminal route or export it from the SOW in the app.

## Accepting an invitation

**Organization invitation.** Open the `acceptUrl` and sign in with the invited address. To do it from a terminal, sign in so you have a session, then use the value after `invitation=` in the link:

```bash
curl -sS --fail-with-body -b "$TANDA_JAR" "$TANDA_APP/api/organization-settings" \
  -H "Origin: $TANDA_APP" -H 'Content-Type: application/json' \
  -d "$(jq -n --arg id "$TANDA_INVITATION" '{action: "accept", invitationId: $id}')"
```

Then set the organization active, as in [step 2](#create-an-organization), to create a token for it. A token belongs to the organization that was active when it was made.

**Project invitation.** Open the link, or use the value after `token=` with an API token from an account with the invited email address. The request must send a JSON body, even an empty one:

```bash
curl -sS --fail-with-body "$TANDA_API/project-invitations/$TANDA_INVITE_TOKEN/accept" \
  -H "Authorization: Bearer $TANDA_TOKEN" -H 'Content-Type: application/json' -d '{}'
```

## If something fails

| You see | What it means | What to do |
| --- | --- | --- |
| `401` from the REST API | The token is missing, wrong or revoked | Check `Authorization: Bearer tnda_...`, or create a new token |
| `401` from `/mcp` | `tnda_` tokens don't work on the MCP server | Connect through your client's sign-in |
| `403 Access denied` | You don't have access to that record, or it's in another organization | Use a token from the organization that owns it, or ask an owner to invite you |
| `403 Invalid origin` | A session request has no matching `Origin` header | Send `Origin: https://www.testandaccept.com` |
| `400 Organization required` | No organization is active for this session | Finish [step 2](#create-an-organization) first |
| `409` on a criterion or test | The SOW version is locked after approval | Change it through an [RFC](/concepts/rfcs/) |
| `415 Missing content-type header` | A `POST` has no JSON body | Send `Content-Type: application/json` and `-d '{}'` |
| `429` | Too many attempts | Wait 10 seconds and try again |
| `Unsupported protocol version` | Your MCP client is too old for the server | Use the Terminal route ([Pi details](/integrations/pi/#protocol-version-error)) |

Source: https://docs.testandaccept.com/agents/journey/index.mdx
