Two people with RelayLink accounts cannot just write. That is the consent gate, and it is doing its job. What it needed — and did not have, for a while — was a way through that was not "hope they are still a provisional mailbox."
A contact request is that way.
Asking
From the assistant: invite_contact with an address. From the browser: contacts. Same service, same pair.
An address nobody has heard of gets a provisional user, the way a cold send does. Asking a real account and asking a stranger look the same from your side. Anything else would answer "does this person have RelayLink?" for free.
Asking twice does not send a second email. The request is not a nudge channel they never consented to.
There is no free text on the request. On purpose. A note from someone they have not accepted is exactly the payload a package is not allowed to carry yet.
Accepting
They see it in their assistant (whats_new lists requests waiting on them) and on their contacts page. accept_contact or the Accept button.
Two checks, not one: the pair involves them, and they are not the person who asked. The second is the whole feature. Without it, a requester could accept on the other party's behalf and every later query would look like consent.
You cannot accept a name that is already an accepted contact, a stranger, or nobody — those three refusals are identical. The tool only reaches the incoming list.
Accepting notifies you. Refusing notifies nobody. You asked; an acceptance is the answer to your question, and the only thing that tells you that you can now send. A block is the opposite on both counts.
Withdrawing
withdraw_invite or the matching control on the page. The pending pair goes. The daily invite budget does not come back — the cap counts requests you made, not rows that still exist.
After they accept
You can send. They can send. A nickname is your word for them, on your side only, unless you tick that they may see it.
A request never resurrects a block. Success and "you are blocked" are the same response from the asker's side. Unblocking is a separate verb, and it deletes the row rather than restoring whatever you had before — an unblock that restored access would silently re-grant what the block had taken away.
What this replaced
Until requests existed, the only accepted pairs in a live deployment were seeded in development. Production sends to other account holders were impossible. Cold email to people who had never signed in still worked. The gate's own error said the rest would arrive later.
It is here now, on the assistant and in the browser. The rule that remains is not a hidden check: the assistant invites when you ask it to, in your own message, the way it sends only when you approve.
If they do not have an account and you just need to reach them, write anyway — that path is email, not a pair.