JT | writeoffs.ai

1K posts

JT | writeoffs.ai banner
JT | writeoffs.ai

JT | writeoffs.ai

@jtkeepsmore

Building https://t.co/i37CfMqDz0 to help self-employed people keep more of what they earn.

Katılım Mayıs 2007
667 Takip Edilen2K Takipçiler
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@WiFiMoneyGuy $8k/mo is a steal compared to a full-time hire when you factor in salary, benefits, and the ramp-up time. Smart businesses are realizing they can get 80% of the value at 20% of the cost with the right consultant. Great positioning for freelancers who go deep on AI.
English
0
0
1
187
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@AminZecom That tool cost to revenue ratio is wild. Most people underestimate how much of the grunt work in an agency can be automated now. The real skill becomes knowing which workflows to automate first and which still need a human touch.
English
1
0
0
139
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@thealepalombo The "not remitted onshore" part is key and a lot of people miss it. For freelancers earning in USD from US clients, Japan can be incredibly tax efficient for those first five years. Just make sure you still handle your US filing obligations if you're a citizen.
English
0
0
0
22
Alessandro Palombo
Alessandro Palombo@thealepalombo·
Japan doesn't tax foreign income for the first 5 years, as long as it's not remitted onshore. Three entry routes worth knowing: 1. Digital Nomad Visa: the easiest. 6 months, won't make you tax resident. 2. Startup Visa: gives you up to 2 years to prepare for a business visa, no capital required upfront. 3. Business Manager Visa: the long-term play, now requiring 30M yen (~$180K) capital in a company. I'm working with a Japanese friend on a full guide, covering not just the legal framework but local perspectives on towns, lifestyle, and what actually works on the ground. Has anyone moved there recently? Questions you want you see answers? Drop them below.
Alessandro Palombo tweet mediaAlessandro Palombo tweet media
English
22
9
238
27.6K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@ryanashcraft 6.5 years with no full-time employees is the part people need to hear. So many founders give up after year two when the growth feels slow. The patience to keep compounding is the real competitive advantage.
English
0
0
0
247
Ryan Ashcraft
Ryan Ashcraft@ryanashcraft·
Foodnoms has officially hit $50K MRR. Bootstrapped with no full-time employees. Took 6 and a half years to get here. The grind never stops. Still working to make the product better every day. I love this little app. Glad others do too!
Ryan Ashcraft tweet media
English
45
5
282
17.1K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@SwannMarcus89 The self-employment tax hit is real. A lot of first-time freelancers don't realize they owe both halves of FICA until that first quarterly estimate. Setting aside 25-30% of every payment from day one is the move that saves people.
English
0
0
0
4
Swann Marcus
Swann Marcus@SwannMarcus89·
I always see people claim that whenever a second tier “content creator” whines about being poor the must be lying because they make too much money No, they’re actually poor. They live in LA and are self-employed. Your employer pays half your FICA taxes, gives you 3-5% 401k matching, and pays 85% of your health insurance premiums. Those three benefits alone mean if you make 80 grand working for a corporation, you’d probably need to make $20,000 more to have the same standard of living if you had to pay all of FICA, 100% of insurance premiums, and had no 401k match and that’s before you consider how many “influencers” are renting in California Also, they’re stupid so a lot of them don’t set enough aside for taxes and wind up in massive debt to the IRS
English
15
28
771
37.8K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@socoloffalex This is so important and so hard at the start. Underpricing doesn't just hurt your income, it signals lower quality to clients. The ones worth working with almost always respect a confident rate.
English
0
0
0
31
Alex Socoloff
Alex Socoloff@socoloffalex·
For all my freelancers at the beginning of their journey. Be confident and comfortable naming your price. Stop asking “do you have a budget in mind?” the second a client asks for your price. Know your worth - name your quote! Confidence always attracts the right entrepreneurs.
English
31
6
148
4.6K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@jayvraavi Zero employees, $2M ARR, profitable, 99% organic. That's the operating leverage most founders spend years chasing. No payroll, no CAC eating margins, just product and distribution. The 'built while traveling solo' detail matters too. Constraints force real creativity.
English
0
0
0
11
jay
jay@jayvraavi·
nomadtable just hit 1M users in under a year profitable. $2M run rate. zero employees. 100% bootstrapped. 99% organic (350M+ short-form views) built while traveling the world solo am i the first bootstrapped solopreneur to build a 1M user social app? 👀
jay tweet media
English
139
19
753
84.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@jayvraavi Zero employees, $2M ARR, profitable, 99% organic. That's the operating leverage most founders spend years chasing. No payroll, no CAC eating margins, just product and distribution. The "built while traveling solo" detail matters too. Constraints force real creativity.
English
0
0
0
10
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@thejustinwelsh The people giving that advice usually have their own fears about leaving, dressed up as concern for you. When you make the leap, you realize the stability you had was mostly just familiarity. The real risk was staying.
English
0
0
0
404
Justin Welsh
Justin Welsh@thejustinwelsh·
The worst career advice I ever got: "Stay where you are, you're lucky to have such a good thing going for you."
English
186
74
1K
46.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@levelsio Classic indie hacker move: you hit a painful ops problem, solve it for yourself, and suddenly every other bootstrapped founder wants the same thing. Disputes are one of the most annoying revenue leaks for solo SaaS operators. This kind of automation pays for itself fast.
English
0
0
3
478
@levelsio
@levelsio@levelsio·
✅ Done 💳 Made an auto-dispute response system for Interior AI to see how easy it'd be It syncs old disputes but also catches new disputes via Stripe webhook and then auto submits evidence to try win them, it even includes the interior designs they generated in the evidence PDF to prove they used it! Here's the prompt/skill I made: ---- Build an auto-dispute-response system for Stripe that: 1. Shared evidence collection (app/dispute_evidence.php) Create a shared file with functions used by both the webhook and sync worker. This avoids duplicating evidence logic. Key functions: - getDisputeUserPlan($user, $stripe) — pulls the user's subscription plan from Stripe API (source of truth, since local DB plan field gets cleared on cancellation). Falls back to local DB fields if Stripe call fails. Maps product IDs to plan names and includes price/interval and canceled status. - collectDisputeEvidence($stripe, $user, $email, $charge, $photosDb) — collects all text and file evidence, returns an array ready to submit to Stripe. - generateServiceDocPdf($stripe, $user, $email, $photos_done, $recent_photos, $total_amount_paid) — generates a PDF with customer info, usage summary, recent activity table, and up to 6 actual product images (resized to JPEG at 500px wide / quality 75 to stay under Stripe's 5MB file upload limit). Returns both the Stripe file ID and raw PDF data. Important: pull total_amount_paid from Stripe charges API (sum of succeeded, non-refunded charges) instead of trusting the local DB which can be null/stale. 2. Webhook handler (in stripe_webhook.php) Catch `charge.dispute.created` events. When a dispute comes in: - Get the dispute, charge, and customer objects from Stripe - Look up the user in the local database by stripe_customer_id - Save the dispute to a `disputes` SQLite database (fields: dispute_id, charge_id, payment_intent_id, stripe_customer_id, user_id, email, amount, currency, reason, status, epoch_created, epoch_evidence_submitted, evidence_json, stripe_response, epoch_resolved, outcome) - Call collectDisputeEvidence() to collect all evidence (text + file uploads) - Submit evidence to Stripe via $stripe->disputes->update($dispute_id, ['evidence' => $evidence]) - Send a Telegram notification that a new dispute came in and evidence was auto-submitted Also catch `charge.dispute.updated` and `charge.dispute.closed` events to track dispute outcomes (won/lost) in the database and send Telegram notifications with the result (with emoji: checkmark for won, x for lost, warning for other). 3. Evidence fields submitted to Stripe TEXT fields (write strings directly): - product_description — describe what the product/service is - customer_name — from Stripe customer object - customer_email_address — from Stripe customer object - access_activity_log — detailed usage log: signup date, number of items/actions done, last active date, subscription plan (from Stripe), platform, total amount paid (from Stripe), recent activity with timestamps - uncategorized_text — the "why we should win" argument: customer signed up on X, actively used the service doing Y things, total amount paid, service was delivered digitally/instantly, customer never contacted us for a refund before disputing - refund_policy_disclosure — when the refund policy was presented (during checkout, always accessible at /legal) - cancellation_policy_disclosure — when cancellation policy was shown (during checkout, accessible at /legal, can cancel anytime from dashboard) - refund_refusal_explanation — customer didn't contact us for a refund before filing the dispute - cancellation_rebuttal — proof customer actively used the service and never requested cancellation - service_date — date of the charge (Y-m-d format) FILE UPLOAD fields (upload file to Stripe first via $stripe->files->create(['purpose'=>'dispute_evidence', 'file'=>fopen($path,'r')]), then pass the returned file_xxxxx ID): - receipt — pull the invoice PDF directly from Stripe ($stripe->invoices->retrieve($charge->invoice)->invoice_pdf gives a ready-made PDF URL, just download it and upload as dispute evidence) - service_documentation — generate a PDF containing: customer info section, service usage summary, recent activity table, and up to 6 actual product images/screenshots the customer received. Resize images before embedding (500px wide, JPEG quality 75) to stay under Stripe's 5MB file upload limit. Also save both PDFs to your file storage (e.g. Cloudflare R2, S3) with hashed filenames so they're not guessable but viewable from the admin dashboard. Store the storage URLs in the evidence_json as _receipt_r2_url and _service_doc_r2_url (underscore prefix so they're easy to identify as internal fields). DO NOT use these fields for text — they expect file upload IDs only: service_documentation, cancellation_policy, refund_policy, customer_communication, customer_signature, receipt, shipping_documentation, duplicate_charge_documentation, uncategorized_file 4. CLI sync worker (workers/syncDisputes.php) A script that pulls ALL existing disputes from Stripe's API (paginated with $stripe->disputes->all(['limit' => 100]) and starting_after for pagination), saves them to the local disputes database, and for any that still have needs_response or warning_needs_response status and haven't had evidence submitted yet — auto-submits evidence using the shared collectDisputeEvidence() function. This is needed because the webhook only catches future disputes, not existing ones. Too heavy to run on frontend — run via CLI only (php workers/syncDisputes.php). Saves a JSON cache file with sync results so the dashboard can show last sync time. 5. Mini dashboard (disputes.php with ?key= auth) A simple HTML page protected by ?key= query parameter that shows: - Stats boxes: total disputes, pending, won, lost, disputed last 30 days (amount + count), disputed last 12 months (amount + count), total $ disputed - A note showing the CLI sync command and last sync time from cache - A test form where you enter a stripe_customer_id to preview what evidence would be submitted (without actually submitting) — useful for debugging - A table of all disputes: date, email, amount, reason, status (color-coded badges), evidence submission status, links to both detail view and Stripe dashboard Detail view (action=view&id=dispute_id): - Shows all dispute info, link to Stripe, and a "Regenerate Evidence" button - Shows PDF file links (receipt + service documentation) if available - Shows Stripe file upload IDs - Shows all text evidence fields Regenerate Evidence (action=regen&id=dispute_id): - Regenerates the receipt and service documentation PDFs and uploads to file storage - Updates the evidence_json in the database with new PDF URLs - IMPORTANT: Use fastcgi_finish_request() to send the HTTP response immediately (redirect back to detail page with "regenerating in background" notice), then continue generating PDFs in the background. This prevents frontend timeouts since downloading images and generating PDFs can take 30+ seconds. Add an nginx rewrite for the page (e.g. rewrite ^/disputes/?$ /disputes.php). Make sure it's in the correct nginx config file (check which one the symlink in sites-enabled actually points to). 6. Telegram notifications - New dispute: "{site name} - New dispute from {email} for ${amount} ({reason}). Evidence auto-submitted to Stripe. {stripe_dashboard_link}" - Evidence failed: "{site name} - New dispute from {email} for ${amount} ({reason}). Evidence submission FAILED: {error}" - Dispute won: "{site name} - Dispute WON (checkmark) for {email} - ${amount} ({reason}) {stripe_dashboard_link}" - Dispute lost: "{site name} - Dispute LOST (x) for {email} - ${amount} ({reason}) {stripe_dashboard_link}" - DB permission error: "{site name} - DISPUTE DB ERROR: {error} - check permissions on data/disputes.db" 7. Make sure these Stripe webhook events are enabled in the Stripe dashboard: - charge.dispute.created - charge.dispute.updated - charge.dispute.closed 8. Database permissions The disputes.db file must be writable by the web server user (e.g. www-data). If you create it from CLI as root, fix ownership to match your other DB files. PHP-FPM runs as a different user than root. 9. Dependencies - FPDF (setasign/fpdf) for PDF generation — install via composer require setasign/fpdf - GD extension for image resizing (usually already installed) - Stripe PHP SDK (already installed if you have Stripe webhooks) - AWS S3 SDK for R2/S3 uploads (already installed if using Cloudflare R2)
@levelsio tweet media@levelsio tweet media@levelsio tweet media
@levelsio@levelsio

Okay I'll try to vibe code an automatic Stripe dispute responder that: 1) receives disputes via webhook 2) collects evidence of user sign up and activity 3) puts it in a beautiful PDF 4) submits it back to Stripe for the banks to review Once it works I'll ask it to summarize it and share the prompt/skill here Codebase is too unique per project so prompt/skill makes more sense!

English
107
48
1.1K
311.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@thedankoe The leverage is real. What catches people off-guard is the back-end: quarterly estimated taxes, tracking what's actually deductible, knowing your effective rate as a solo operator. Once you get the financial side dialed in, the one-person upside becomes even clearer.
English
0
0
0
289
DAN KOE
DAN KOE@thedankoe·
You as a single person have more power today than a 20 person company of the past. That's insane. The internet gave you the ability to learn anything. Social media gave you the leverage to reach anyone. AI is giving you the ability to create almost anything. Please don't waste it
English
587
1.3K
10.3K
262.9K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@taxgirl The "I didn't get a 1099 so I don't owe taxes" myth trips up so many new gig workers. The IRS wants its cut regardless of whether a form gets sent. Quarterly estimated payments are the rude awakening most first-year freelancers don't see coming.
English
0
0
1
21
Kelly Phillips Erb
Kelly Phillips Erb@taxgirl·
Gig work is flexible. Gig taxes? Not so much. No 1099 doesn’t mean no reporting—and some new deductions sound great… until you realize there are rules attached. It’s one of those “simple until it’s not” situations. Here’s what to know: 
forbes.com/sites/kellyphi…
English
2
4
22
1.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@Gavel_on_X In the US it's rough too. Self-employment tax alone is 15.3% before income tax kicks in. The only real lever freelancers have is deductions, and most leave thousands on the table by not tracking business expenses consistently through the year.
English
0
0
0
6
Gavel
Gavel@Gavel_on_X·
Looks like being a freelancer in Italy means paying 50% in taxes... Crazy. What’s it like in your country?
English
57
0
80
4.1K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@irentdumpsters The financials look better solo too. No payroll taxes on employees, simpler deductions, and you keep the margin instead of watching it disappear in labor costs. People confuse gross revenue with actual take-home all the time.
English
0
0
1
43
Bodhi- Local SEO
Bodhi- Local SEO@irentdumpsters·
5 home service businesses that will make you $300K/yr as a solo operator. But the second you try to scale past yourself, they'll destroy you. I've watched owners go from clearing $25K/month solo to losing money with a crew of 6. Here's the list and why it happens 🧵
English
16
13
164
71.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@remoteoliver The no-staff piece is underrated financially too. The moment you hire employees your tax complexity multiplies and margins compress fast. Staying lean keeps accounting simple and your profit percentage high.
English
0
0
0
6
Oliver
Oliver@remoteoliver·
The sweet spot. $30k a month (not an empire) 30 hours a week (no full time staff) Location freedom (no office) Premium clients (not volume)
English
39
22
512
26.9K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@thejustinwelsh This framing is underrated. Most people don't realize their W2 take-home was already compressed by taxes they had zero control over. Going solo means you actually get to decide what stays in your pocket through the right deductions and structure.
English
0
0
0
4
Justin Welsh
Justin Welsh@thejustinwelsh·
The most successful solopreneurs aren't scaling to $10M. They're simply making more than they did at their job, minus the boss, meetings, and headaches.
English
198
43
857
36.8K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@agazdecki Zero churn and zero revenue is technically impressive. The real test is retention once people have actual skin in the game. Free users who quietly disappear are a very different signal than paying customers who stay.
English
0
0
0
41
Andrew Gazdecki
Andrew Gazdecki@agazdecki·
When your co-founder says “we don’t have churn” because your startup has zero customers:
English
22
2
89
8.5K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@danmartell For solo founders this is especially true. Most of your best clients, collaborators, and opportunities come from being visible and present, not from a perfect pitch or cold outreach. Showing up in the right conversations is the whole distribution strategy.
English
0
0
0
31
Dan Martell
Dan Martell@danmartell·
What looks like luck is usually just proximity: - Go outside - Say hi - Join conversations - Share what you're building
English
59
11
168
4.1K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@dvassallo The small bets framework gets more compelling every year. One income stream is fragile, but five smaller ones with different risk profiles is actually more stable than going all-in on a single SaaS. The preview is a smart move for showing the depth of what's inside.
English
0
0
1
11
Daniel Vassallo
Daniel Vassallo@dvassallo·
New smallbets.com homepage is live. If you're not a member yet, you can now get a free preview of what's inside. Take a look!
Daniel Vassallo tweet media
English
27
6
113
36.7K
JT | writeoffs.ai
JT | writeoffs.ai@jtkeepsmore·
@thesamparr Building an audience first and then selling the business is the play more indie founders should think about. The Hustle deal proved you can bootstrap a media brand into a real acquisition target without taking VC. The model is replicable for anyone building in a niche.
English
0
0
0
16
Sam Parr
Sam Parr@thesamparr·
In our little world, hubspot buying the hustle was the first of this experiment. They bought our newsletters, blog, trends, podcasts like my first million. And tbh I’m still shocked they were bold enough to do it. It’s been amazing for them (and us). But it’s been done a ton. In the radio days, product companies owned stations. It gets screwed up a ton, though. For example, I think robinhood tried and didn’t pulled it off. The barstool one didn’t seem great, either. It’s worked for hubspot. And others. I’m not sure what makes one of these deals (media + product) successful. One attribute just seems to be a good partnership. A good owner, good creative talent that can manage to like one another. That’s hard! Interestingly, virtually every single media company I know of today, when they try to launch a product - it’s super dumb and fails. It’s much easier, I think, to have a good product then launch media. This is what my company’s doing now. We have a very sticky product and are launching more media properties. Very hard but easier this way. So I think it’s wise to buy a media company and shut down the ads. Ads with a product can work, but make it tough internally. Fighting over ad inventory to promote owned products vs ads. And if you have a big ad sales team, making a product and selling it successfully, forget about it. If a media company says they’re doing it, assume it’ll fail. Ad sales teams need to be fed and will ruin any beauty of a product. Dunno if tbpn plus open ai will win. But John and Jordi won (will keep winning), that’s for sure!
English
29
3
191
22.8K